Part 1: Extending jQuery with plugins. Creating Plugins. Scott introduces himself
and the following program. Creation of a jQuery plugin from scratch.
Scott González: Writing Plugins & jQuery UI
Part 1: Extending jQuery with plugins 0:00:00 - 0:01:09
Creating Plugins
Scott introduces himself and the following program.
0:01:10 - 0:07:49
Creation of a jQuery plugin from scratch. Scott explains the $.fn assignment, iterating over selected elements and keeping chaining intact. He explains where implicit iteration can be used and where not, with a brief excursion on jQuery’s internal traversal stack.
0:07:50 - 0:09:43
How to make plugins actually useful by adding parameters, with an aside on optimizing iteration performance by keeping common computations outside the each-loop.
0:09:44 - 0:14:19
Scott then goes from parameters to options, a common pattern used by most jQuery plugins, removing the ordering requirement and giving each parameter a default.
0:14:20 - 0:27:46
Scott demonstrates how to extend plugins, which comes in handy when a built-in jQuery method or a plugin doesn’t quite do we an application needs. The proxying technique available in JavaScript is here used to override a plugin method, with a few explanations of JavaScript’s call and apply methods and some background on function scopes.
0:27:47 - 0:32:49
0:32:50 - 0:36:49
Plugins & State
Here Scott takes a step back, reviewing how jQuery revolutionized how we work with the DOM, implementing complex tasks by chaining simple tasks together. He explains the common problem of this approach: How do we know the current state of things? How can we build plugins that have state similar to jQuery’s ajax module? And how do we interact with that state, say, beyond aborting an ajax request? He uses dialog as an example plugin, where you want to know the openness state of the dialog, then open and close it accordingly. From here Scott goes through a few options for managing state, something that jQuery itself doesn’t provide any guidance about. These are the options that were originally considered when jQuery UI was created, so naturally Scott concludes with the approach taken by jQuery UI, exposing a single method that then proxies to other methods. That single method is also used to initialize the plugin in the first place.
1
Part 2: jQuery UI overview 0:36:50 - 0:38:46
0:38:47 - 0:39:32
0:39:33 - 0:41:06
jQuery UI API overview
From here Scott introduces the basic API used for all jQuery widget’s building on top of the previous section about state management. He starts with the single method that each widget exposes, used both for initialization and calling other methods. He also covers events and callbacks, used as actual, prefixed events or as options. Scott starts this long live coding section with an overview of the components available in jQuery UI, which he’ll cover one by one for most of the remaining workshop.
Draggable
Draggable allows elements to be dragged with the mouse and exposes options to customize that behaviour. Scott goes through a few of them, starting with the axis option. He shows how options are readable and writable through the option method, even after a widget was initialized.
0:41:07 - 0:42:32
Scott explains Draggable’s helper option, which is useful when the element to be dragged is rather complex, or you just want to have a clone, as in a drag-to-shopping-cart context.
0:42:33 - 0:46:18
Using “dragstart”, “drag” and “dragstop” as example, Scott shows how to bind to Draggable’s events. Instead of just logging events, he shows how to use them to customize Draggable’s behaviour, for example constraining the movement beyond what the built-in options like axis offer.
0:46:19 - 0:48:06
Scott closes the section on Draggable showing the handle option, useful when a draggable element contains other interactive content, and the disabled method.
0:48:07 - 0:50:57
Droppable
Droppable is the counterpart to Draggable, providing all the tools you need to build a drag’n’drop interface. Scott shows how to add visual feedback when starting to drag or hovering over a drop target, using the activeClass and hoverClass options. He covers the accept option, used to restrict which draggable is allowed to connect to a droppable. He demonstrates the various values for the tolerance option, used to customize the hit areas.
0:50:58 - 0:53:12
Of course Droppable also has events and a disable method. Scott shows the “drop” event in combination with the disabled option, to disable the droppable after a draggable was dropped. Instead of disabling, the Draggable can also be destroyed, using the destroy method, which is also available for all other widgets, similar to the disable/enable methods.
0:53:13 - 0:56:32
Scott responds to a question about making an element both clickable and draggable, showing the distance option in action.
2
0:56:33 - 0:59:22
0:59:23 - 1:05:08
1:05:09 - 1:07:43
Resizable
Resizable is the only interaction component with a visual interface, indicating where to drag in order to change the size of an element. Not all handles are visible though. Using the handles option, you can specify which handles should be used. Scott then shows how to synchronize the resize effect to another element and how to restrict the resizing to minimum or maximum width or height. Here Scott shows how to resize a kitten. That is, how to make an image resizable. Along with using the resize event (or callback) to log or implement a custom constraint, similar to the events on draggable. Of course for the most common constraints, option exists, like the aspectRatio option: Set to true, it will keep the original aspect ratio.
Sortable
Sortable allows the user to reorder elements within a list. It supports similar options as draggable for specifying handles and helpers. In addition to those, Scott shows the placeholder option, giving more visual feedback, while dragging, about where an item is being placed.
1:07:43 - 1:09:00
Scott demonstrates the items and cancel options, both about specifying what items to inor exclude from sorting.
1:09:01 - 1:16:34
When dealing with multiple lists, the connectWith option allows sorting elements from one list to the other. Along with the regular start/sort/stop events, this adds more events like receive. If you don’t want to keep track of changes using events, you can use the serialize and toArray methods to retrieve the order of elements.
1:16:35 - 1:21:00
Accordion
The Accordion is the first widget Scott introduces. It takes a group of header and content panel pairs and transforms it, applying themes and mouse/keyboard interactions. Scott shows how different values for the heightStyle option cause the Accordion to fill according to the biggest panel, the surrounding content or the height of the parent element.
1:21:01 - 1:21:47
Scott next shows more Accordion options, starting with “active”, to control which panel to show first. And the collapsible option, which by default prevents all panels from closing.
1:21:48 - 1:27:52
The Accordion accepts quite a lot of base markup, like unordered lists or definition lists. Some markup actually gets generated by the accordion. To customize the generated icons, use the option of the same name.
1:27:53 - 1:30:08
As other widgets and the interactions, Accordion also has events. Scott shows the activate option in action, triggered whenever another panel is opened.
1:30:09 - 1:33:11
Autocomplete
Autocomplete enhances a regular text input to provide suggestions while the user is typing. Scott shows the various ways to feed those suggestions into the widget, all using the source option. It accepts an array for local data, a string to point to a server resource, or a function to provide dynamic data on the client. 3
1:33:12 - 1:33:50
When accessing remote data, it makes sense to delay the actual request to wait for the user to finish typing. The delay option can be increased from the default of 300ms, or decreased to provide an even more responsive behaviour for local data.
1:33:51 - 1:37:01
Autocomplete provides events for pretty much every interaction, from the user’s typing causing a search to start, to mouse or keyboard interaction focussing or selecting an item. If the input changed and its blurred, a change event is triggered, similar to the native change event, but more reliable. Here Scott shows how the suggested data can consist of more then just the display value, for example to store a database id in a hidden field, based on the selected item.
1:37:02 - 1:39:32
Next Scott demonstrates the widget method, which is available to all widgets in jQuery UI. For most it just returns the element that the widget is applied to, but for Autocomplete it gives you access to the suggestions menu.
1:39:33 - 1:42:32
Button
Button can be applied to regular button elements, anchors or input of type submit. It also works with checkboxes and radio buttons, as long as those are properly marked up with a label element. For checkboxes and radio buttons, the buttonset method also provides visual grouping, instead of only styling each indivdual button.
1:42:33 - 1:45:36
Scott shows the icons option, which is quite similar to how icons work for Accordion. Though buttons can have both primary (left) and secondary (on the right) icons. They can also be used together. By default Button uses existing text in the markup, which can be overriden using the label option. The text can also be hidden using the text option, as long as icons are specified.
1:45:37 - 1:47:56
Depending on what markup is used, the widget method comes in handy, as the original markup might not match the tranformed button markup. For a radio button, it gives you access to the label element that serves as the visual part of the button.
1:47:57 - 1:51:07
Datepicker
Datepickers can be tied to inputs, but can also show up inline. Scott demonstrates both, along with the minDate and maxDate options. Using new Date for one of these restricts the datepicker to any date before or after the current date.
1:51:08 - 1:53:35
Scott shows Datepicker’s internationalization support, switching his demo from English to French by just including one more script. He also explains the dateFormat option, used to configure specifying the format of the resulting date, also very useful based on locale and culture.
1:53:36 - 2:05:23
Marc, who originally wrote the datepicker, shares a bit of the implementation story of Datepicker. Scott adds some of his own experience with the API design of jQuery UI and dealing with hundreds of feature requests and different usecases. In the end, don’t try to solve everyone’s problems. 4
2:05:24 - 2:07:50
Dialog
Dialog takes an existing element and wraps some UI around it, then shows that element centered on the page. It can have a title, specified in the markup as a title attribute or through the title option. Draggable and Resizable are used, if available, to move or resize the dialog. Both can be disabled.
2:07:51 - 2:09:55
Similar to Resizable, the dimensions of the dialog can be restricted using the height, minHeight, maxWidth, width, minWidth and maxWidth options.
2:09:56 - 2:16:35
Scott answers a question about stacking dialogs, demonstrating how an element inside a dialog can open another dialog. He also answers another question about dialog’s and form elements, showing how the dialog widget takes the existing element and wraps it with a new element, but never cloning it. From there Scott takes a short detour on explaining problems with modal dialogs and z-index handling and his idea on solving that problem with a much simpler solution.
2:16:36 - 2:21:30
Coming around from the original state management example, Scott shows how to close a dialog from a timeout, using the close method. He also explains the autoOpen option, and how that tended to cause trouble for new developers, until newer versions of jQuery UI shipped with a workaround built in.
2:21:31 - 2:23:17
2:23:18 - 2:24:06
2:24:07 - 2:27:29
2:27:30 - 2:28:43
Progressbar
When uploading a file, its generally a good idea to show the progress of that upload, with a visual indicator along instead of just a text status. For that, Progressbar can be used. Apart from setting the range using the max option and the current value (value option), there’s really not much the widget does. It’ll give you a complete event when the value reaches the max value. Scott talks about the plan to make the progress support a false value, making the progressbar indeterminate. That’ll be useful when the end value is not clear yet, but setting the value later will be possible, having it switch to a determinate progressbar.
Slider
Slider is useful whenever you need to input a number value, and precision isn’t important. A slider can have just a single handle for a single value, but also multiple handles, for example two handles to input a range. Specifically for that case Slider has a range option, highlighting the area between the two handles. Scott also shows the orientation option, turning the slider 90º to display it vertically, instead of horizontally. Another customization option is provided by the step option, which controls the allowed values, for more coarse-grained inputs.
5
2:28:44 - 2:31:07
Spinner
Spinner is another widget for number values, but more useful for precise values. It has similar options to Slider, like min, max, step and page, but will produce only a single value, not multiple ones. Unlike Slider, Spinner starts off with a regular text input, then enhances that.
2:31:08 - 2:33:34
For programmatic control, Spinner exposes a few methods for stepping or paging up and down. Scott shows that in action with a timer. He also shows how by default the spinner increases incrementally, so that the increase per step increases over time. That can also be disabled to get a static increment.
2:33:35 - 2:36:10
Spinner also supports formatting and internationalization, but dealing with numbers, not dates like Datepicker. It’s trivial to have the format input and parse a currency value, as long as the Globalization library is included. Scott shows how to switch a currency spinner from the default English locale to a German locale.
2:36:11 - 2:36:35
Scott mentions the events exposed by Spinner, covering the usual pattern of spinstart, spin, spinstop and spinchange.
2:36:36 - 2:38:06
Tabs
Tabs are somewhat similar to the Accordion, except that all the headers are in one two, instead of being paired with each panel. The base markup uses a list for the headers, linking each header to the panel using an a-element with an hash-href attribute. Tabs have the same active-option as Accordion.
2:38:07 - 2:41:42
Unlike Accordion, Tabs support loading the content of a panel through ajax, either loading the content each time a panel is opened, or loading it just the first time. If dynamic content is generated on the clientside, you can call the refresh method any time after adding that new content to the base markup.
2:41:43 - 2:47:13
Scott answers a question about nesting tabs, which generally works. The one thing to be careful about is how nested tabs have events bubbling up to the parent tabs widget, which can cause confusion. Scott also briefly talks about Accordion here, which needs to be visible when intialized, something that doesn’t apply to Tabs. Generally jQuery UI widgets can be nested pretty heavily, and he shows a demo of a Draggable within an Accordion within an Accordion within Tabs within a Dialog, which is also draggable. He also shows a few other cases of combining interactions and widgets, which have some limiations here and there that are being worked on.
2:47:14 - 2:52:16
Position
The Position utility is all about taking away the burden of relative positioning math from the developer, making it really easy to position one element relative to another, taking into account the dimensions of the window to make sure the element is actually visible at the end. Scott demonstrates the really simple API that the utility exposes, along with the built-in collision detection that supports both flipping and fitting, or even a combination of both.
6
2:52:17 - 2:53:53
Next Scott shows how the using option can be used to animate the actual positioning, including a (questionable) bounce effect.
Part 3: Widget Factory 2:53:54 - 2:57:13
The Widget Factory is the underlying abstraction used for all the jQuery UI widgets and interactions (with the exception of datepicker, at the time of the recording). Scott builds a colorbox widget using the widget factory, rebuilding the color plugin from the beginning of the workshop. Defaults are specified in a options property, _create serves as the constructor of the widget.
2:57:14 - 2:57:56
While writing the colorbox implementation, Scott answers a question about the dependencies of the Widget Factory: It depends only on jQuery itself, but doesn’t have any dependencies on other modules within jQuery UI. The same applies to the Position plugin.
2:57:57 - 2:29:17
Scott explains the colorbox code so far and what the Widget Factory abstracts a way, like merging options with defaults and creating a widget instance for each selected element. Unlike the original plugin, he can now ask the widget for its state, without having to do any DOM queries.
2:59:18 - 3:01:49
Reading options works, but in order to update options at runtime, that is, after initialization, some extra code is necessary. Scott shows how to override the _setOption method to make that happen.
3:01:50 - 3:03:03
Next Scott shows how private methods, those prefixed with an underscore, can’t be called through the plugin wrapper. For any public methods that the user is supposed to use, leave out the underscore to make them available through the wrapper.
3:03:04 - 3:07:49
Scott answers a question about triggering custom events by adding a random method, that picks three random hex values to generate a random color, then uses _trigger to create a custom event. Scott explains the three arguments that _trigger accepts, using the third one to pass along the generated colors. He then shows how to implement the prevention of a default behaviour via custom events, by looking at a false return value from _trigger.
3:07:50 - 3:11:04
To deal with events within a widget, Scott talks about using _bind (note: in 1.9 final now called _on). In the widget context, this provides a bunch of advantages over using jQuery’s event binding methods: It keeps the widget instance context intact and doesn’t call the callback when the widget is disabled. It’ll also take care of automatically cleaning up events, as long as they’re bound through the _on method. For any custom cleanup, Scott shows how to implement the _destroy method, here removing the button he generates within the _create method.
3:11:05 - 3:12:33
From there Scott shows how to access the plugin instance directly, using jQuery’s data method. Accessing the instance itself removes the need to call methods through the plugin wrapper, but also gives access to all private methods or the element the instance is applied to.
7
3:12:34 - 3:14:56
Scott answers a question about the advantage of one approach over the other (plugin wrapper vs direct access of plugin instance). Scott explains that the wrapper approach is much more familiar to jQuery users, making it more useful most of the time. When direct access is more useful or natural, accessing the instance directly might make more sense. Its even possible to instantiate an instance without going through the plugin wrapper and using the data method.
3:14:57 - 3:18:16
Inheriting from existing widgets is done the same way as extending existing widgets, using a second argument to the $.widget method. Here Scott takes a little detour explaining how inheritance, prototypes and constructors work in JavaScript. He then goes back to options for extending widgets with 1.8 and 1.9, where its really easy to stick new methods on existing widgets.
3:18:17 - 3:19:00
Marc briefly shares his story of writing his own abstraction similar to the Widget Factory, but ending up with throwing that away and actually using the Widget Factory instead, something Scott has heard from a lot of developers.
Part 4: jQuery UI CSS Framework & ThemeRoller 3:19:01 - 3:25:03
To close this workshop, Scott briefly covers the jQuery UI CSS framework. He covers the components: containers, clickable and system states, interaction cues and icons. He demos jQuery UI’s ThemeRoller tool to give examples for each and also show what ThemeRoller is capable of.
3:25:04 - 3:26:21
As a closing note, Scott briefly covers what else jQuery UI has to offer, like effects, all available on jqueryui.com.
8