Advertisement

What you Should be Excited About in jQuery UI 1.9

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

jQuery UI 1.8 has been around for a little while now. In fact, it's currently on version 1.8.16. jQuery UI 1.9 is under active development and brings a number of new widgets to the table, along with the usual improvements in stability and performance.

The biggest changes are, of course, the new widgets themselves, but there have also been modifications to some of the existing widgets. We'll look at the new widgets first. The widgets are in the advanced stages of development, but you should be aware that the widget's APIs are still subject to change until they are fully finalized.


The Menu Widget

The menu widget can be used standalone to transform a list of hyperlinks into a themeable, keyboard and mouse navigable menu

The menu widget, previously part of the autocomplete widget, has been broken out into its own plugin for reuse in other components. It can be used standalone to transform a list of hyperlinks into a themeable, keyboard and mouse navigable menu, but is best used in conjunction with other widgets.

It features the disabled option, which is shared by all jQuery UI widgets, as well as the position option which uses the position utility to position itself relative to another element. It exposes the standard set of methods; destroy, disable, enable, option and widget, as well as the unique method refresh which is used to update the menu when new items are added to it. It also fires a range of event hooks including create, focus, blur and select. The last three events are passed an object referring to the individual item that was focused, blurred or selected.

Using the widget is extremely easy, of course. For example, we could transform a simple select box into something more attractive using the menu widget:

We'll need our script to read through the options in the <select> box we are replacing and build a new unordered-list which will serve as the base of the menu widget:

<script>
	(function ($) {
                
	//cached els
	var base = $("#selectmenu").hide(),
		container = $("<div />", {
			"class": "ui-menu-container ui-widget ui-widget-content ui-corner-all"
		}),
		label = $("<span />", {
			id: "label",
			text: "Choose..."
		}).appendTo(container),
			list = $("<ul />", {
			id: "menu"
		}),
		item = $("<li />");

	//build underlying list for menu
	$.each(base.children(), function () {

		var tempItem = item.clone();

		$("<a />", {
			href: "#",
			text: $(this).text()
		}).appendTo(tempItem);
	
		tempItem.appendTo(list);
	});

	list.appendTo(container);

	//build menu opener
	$("<a />", {
		"class": "ui-menu-trigger ui-widget-content ui-corner-all",
		href: "#",
		html: "&amp;#x25BC;",
		click: function () {
			$("#menu").slideDown();
		}
	}).appendTo(container);

	container.insertAfter(base);

	//init menu
	$("#menu").hide().menu({
		select: function (e, ui) {
			//set selected index on hidden <select>
			base.attr("selectedIndex", ui.item.index());

			//update ui
			$("#label").text(ui.item.text());
			$("#menu").slideUp();
		}
	});

} (jQuery));

The first chunk of code caches a selector for the <elect> box and creates the elements that we'll need. The next section uses jQuery's each() method to read each <option> and create a corresponding <a> element for it. Once an entire list has been created, we can then initialize the menu widget using the list as its underlying structure. This is done using the menu() method and passing in a configuration object in order to use the select event, which is triggered every time a selection from the menu is made.

Within our callback function, we first make sure we update the selectedIndex of the <elect> box our fancy menu is replacing. We can find out the index of whichever menu item was selected using the items property of the ui object passed to our function as the second parameter. We also update the text in our replacement and hide the menu.

Obviously this is just a quick example to highlight how the menu widget can be used as part of another widget, not an instruction on creating jQuery UI widgets. For details of the CSS and HTML used, see the code download.


The Menubar Widget

The menubar widget is used to create a horizontal menu which supports any number of nested menus, menu icons, keyboard navigation and full theming.

One of the new widgets in the library that makes use of the menu widget is the menubar, which is used to create a horizontal menu which supports any number of nested menus, menu icons, keyboard navigation and full theming.

The best way to understand the role of the menubar is to see it in action; the underlying mark-up is simply an unordered list structure:

<ul id="menu">
	<li>
		<a href="#">File</a>
		<ul>
			<li><a href="#">New</a></li>
			<li><a href="#">Open</a></li>
			<li><a href="#">Close</a></li>
		</ul>
	</li>
	<li>
		<a href="#">Edit</a>
		<ul>
			<li><a href="#">Undo</a></li>
			<li><a href="#">Redo</a></li>
		</ul>
	</li>
	<li>
		<a href="#">View</a>
		<ul>
			<li><a href="#">Home Screen</a></li>
			<li>
				<a href="#">Zoom</a>
				<ul>
					<li><a href="#">150%</a></li>
					<li><a href="#">120%</a></li>
					<li><a href="#">100%</a></li>
					<li><a href="#">80%</a></li>
					<li><a href="#">50%</a></li>
				</ul>
			</li>
		</ul>
	</li>
</ul>

A <ul> element is all we need. Any number of sub-menus can be used which are represented by nested <ul> elements. To initialize the widget, all we need to do is call the widget's menubar() method:

$("#menu").menubar();

That's it; that one line of code will initialize the widget and transform our list into an attractive menubar:

To change the appearance of the top-level menu items, so that they look like buttons, and/or to add sub-menu indicators, we can use the buttons and menuIcon configuration options within the menubar() method:

$("#menu").menubar({
	menuIcon: true,
	buttons: true
});

The other configuration options we can use are autoExpand, which makes the submenus appear on hover instead of click, and position, which allow us to position the widget wherever we like in relation to another element. This option hooks into the separate position widget, just like it uses the menu widget to create the submenus.

At this point, the submenu items don't actually do anything, so other than looking pretty, it actually does nothing. To change that we can use the select event which the underlying menu widget exposes to execute arbitrary code that makes the menu function. This widget only exposes the standard suite of methods; destroy, disable, enable, option and widget.


The Spinner

The spinner widget is a great new addition to the library; its premise is simple, but its effect is great and I think I'm not alone in saying that I've been waiting for it to appear for some considerable time!

It adds up and down buttons to a text <input> so that its value can be incrementally increased or decreased without typing; an instant win for the user-experience.

Let's see it in action; for the default behaviour, all we need is a simple <input> on the page (with an id of spinner in the example), and a tiny bit of script:

<script>
    (function () {
        $("#spinner").spinner()
    } (jQuery));
</script>

This gives us the attractive and fully keyboard-accessible spinner:

The API for spinner is extensive with a range of configurable options, custom events and methods. The options we can use to configure the widget are as follows:

  • incremental
  • max
  • min
  • numberFormat
  • page
  • step

The unique methods we can use to trigger specialist behaviour in the widget include:

  • stepUp
  • stepDown
  • pageUp
  • pageDown
  • value

There are also some custom events we can use to hook into key interaction, which are as follows:

  • change
  • spin
  • start
  • stop

Rich Tooltips

The tooltip widget allows us to create rich, attractive tooltips using, by default, the title attribute. Any element that can have a title attribute can have a tooltip added, providing helpful supplementary information to a form using simple links.

<label>Name:</label><input /><a href="#" class="tip" title="Your actual name, you don't need help with that right..?">?</a>
<label>Age:</label><input /><a href="#" class="tip" title="The length of your existence">?</a>

Then all we need to do is call the tooltip method on our elements:

$(".tip").tooltip();

This will generate tooltips using the title attributes of the elements:

As well as using the title attribute, we can use the content configuration option to specify an alternative means of adding content to the tooltip, we could use the text content of a hidden <span> element for example:

<label>BMI:</label><input /><a href="#" class="alt-tip" title="This will not be used">?</a>
<span id="bmi">To calculate your BMI simply divide your height in Kilograms by your height in metres squared<span>

$(".alt-tip").tooltip({
	content: function () {
		return $("#bmi").text();
	},
	position: {
		my: "center bottom",
		at: "center top"
	}
});

Now the tooltip will take the text content of our <span>:

We also use the position configuration option to reposition the tooltip in this example.


Popups

The popup widget should also be ready for the 1.9 release. Like the menu widget that we looked at earlier, the popup is a low-level widget that is designed to be used by other widgets.

It's actually even more low-level that the menu and has no visible UI itself. It will eventually form the basis of all widgets that show any kind of popup, so expect to see it listed as a dependency for the menu, the tooltip and probably other widgets such as the dialog.


Summary

jQuery UI 1.9 will be a special release, much like 1.7 was a couple of years ago. Not only does it bring new widgets to the UI toolkit at our disposal, bug fixes and performance enhancements, it will also bring many changes to the API of each individual widget.

jQuery UI is currently undergoing a huge rewrite, with all existing widgets recreated with new, simplified APIs that will make learning and extending the library much easier, with these changes culminating in version 2.0. Some of these rewrites will introduce breaking changes to existing widgets. This is unavoidable, and in fact, is essential if we wish to see the library progress, but to make the transition easier rewritten widgets will continue to function using existing syntax throughout the life-cycle of 1.9 and the old APIs will not be fully removed (where possible) until the 2.0 release.

So this is the beginning of a hugely exciting time for users of jQuery UI, with new widgets appearing, better APIs and improved performance and a general refinement to all aspects of the official UI library for jQuery.


Advertisement