Archive for the 'UI' Category

Using Jeditable for inline editing

Thursday, February 4th, 2010

Using the Jeditable plugin for jQuery enables inline editing of a block of text. This makes it easy to take a static view and simply drop in editability. Say we start with the following HTML:

<label>Name:</label> <span class="employeeName">Ben Scott</span><br/>
<label>Rating:</label> <span class="employeeRating">Highly awesome</span>

We want to be able to edit the employeeName and employeeRating spans. We need two actions (asssuming an MVC framework) to update the name and rating. The URLs might be something like /employee/set_name/{id} and /employee/set_rating/{id}. Each action should accept HTTP POST, take the new value in $_REQUEST['new_value'] or similar, and return a HTTP status of 200 on success and 500 on failure, with the error message in the response. For example, using Slab (my PHP5 MVC framework, in development) the set_name action might be like this:

class EmployeeController extends AppController {
	function set_name($id) {
		$this->Employee->save(array(
			'id' => $id',
			'name' => $this->data['new_value']);
		));
		return $this->ajaxSuccess($this->data['new_value']);
	}
}

Slab catches uncaught exceptions and returns an AJAX failure with the exception message as the body of the response.

To hook up the fields to the actions, modify the HTML to include the URLs to the actions. While this means the markup has behavioural elements and isn’t purely presentational (and has a non-standard attribute), it makes the script a bit simpler and easy to move into a static .js file, and is a quick way to get a page working.

<label>Name:</label> <span class="employeeName" editUrl="/employee/set_name/7">Ben Scott</span><br/>
<label>Rating:</label> <span class="employeeRating" editUrl="/employee/set_rating/7">Highly awesome</span>

Now for the script itself:

$(function(){
	$('.employeeName, .employeeRating').editable(
		function(value, settings) {
			return $.ajax({
				url: $(this).attr('editUrl'),
				data: { 'new_value': value },
				async: false,
				type: 'post'
			}).responseText;
		}, {
			indicator: 'Saving...',
			tooltip: 'Click to edit',
			onblur: 'submit'
		}
	);
});

The first argument is a function that returns the new value of the field. This is important when doing things like replacing line breaks with <br/> which we’re not worrying about, but it also gives us the ability to write our own AJAX code. By default Jeditable makes assumptions about how the update is done. The async option in the call to $.ajax() blocks until the call returns, and lets the function return the response of the AJAX call. The second argument are options to set some text to show while calling the update function, the tooltip to display when hovering over the span, and to submit changes on blurring the input which makes it seem a bit more usable when there are multiple fields.

Form validation with jQuery

Wednesday, December 9th, 2009

Every time I’ve implemented client-side form validation I’ve started from scratch and done it a little differently. Usually it devolves into a messy set of if statements and duplicated code. Here’s my latest method, which separates the validation rules from the processing. It uses jQuery because if you’re not using a Javascript library you should be. This will only handle relatively simple validation cases.

So start with a form:

	<form id="mailingListSubscription" action="subscribe.php">
		Name: <input type="text" name="name" id="name" /><br />
		Email: <input type="text" name="email" id="email" /><br />
		Phone: <input type="text" name="phone" id="phone" /><br />
		<button type="submit">Subscribe</button>
	</form>

All fields are required, and I’m going to use some magical regex (found on the interthingy somewhere) to validate the email address. This script sets up the rules:

	var rules = [
		{ id: 'name', test: function(val) { return val != ''; }, msg: 'Please enter your name' },
		{ id: 'email', test: function(val) { return val.search(/^[^@]+@[^@]+.[a-z]{2,}$/i) != -1; }, msg: 'Please enter a valid email address' },
		{ id: 'phone', test: function(val) { return val != ''; }, msg: 'Please enter your phone number' }
	];

Each rule has the id of the form element being tested, a message that gets displayed on failing the rule, and a function that validates the value of the form element. I also could add multiple rules for the one input.

This script sets up the submit handler for the form, which does the validation using the array of rules set up above:

	$(function(){
		$('form#mailingListSubscription').submit(function(){
			for (var i = 0; i < rules.length; i ++) {
				var rule = rules[i];
				var target = $('#'+rule.id);
				if (!rule.test(target.val())) {
					alert(rule.msg);
					target.focus();
					return false;
				}
			}
			return true;
		});
	});

On a test failing, the rule’s msg value is shown and the target of the test gets focus. This could be changed to something more user friendly like showing the message next to the target field.

ZedGraph – .NET graph control

Friday, March 28th, 2008

Today I needed a graphing control, and with a bit of searching found ZedGraph. This has got to be the best open source .NET component I’ve ever used. All you need to do is reference the .DLL, drop a ZedGraph control onto your form or control, and add some code to load in a data range. It’s even easier to make a pie chart and the colours, gradients, etc., are all customisable. Out of the box the control automatically has zooming, scaling, printing and exporting features accessible to the user, and it looks nice and clean. There’s also a ZedGraphWeb control built in which is for use in ASP.NET apps (although I haven’t tried that out).

There are two concurrent versions for both .NET 1.1 and .NET 2 (which is very handy since I’m limited to .NET 1.1 at work). The only difference between the versions is apparently use of templates for collections.

There’s a CodeProject article that gives a pile of simple demo code, and the main site is a Wiki with what looks like plenty of documentation. The library is licensed under the LGPL license, which means that derivative works must be LGPLed, but as long as the library’s DLLs are dynamically linked they can be included in commercial software.