Friday, October 26, 2012

Thoughts on Extending jQuery UI Spinner: Adding a Slider Widget

I've been thinking more about the spinner and how to best extend its functionality beyond the basic options it currently offers.  I really like the simplicity of the current design and don't really want to disrupt that basic implementation. 

Most enhancements probably fall into two categories:

  • Additional visual components to assist in picking values. These might include a slider to quickly move to a different point in the valid range or a drop down menu with common choices.

  • Other formatted values that are incremental in nature.  Anything that can be represented as a number can be used with the spinner widget. Dates and times seem like excellent candidates to use with the spinner.

The question becomes how much functionality should be included/supported by the base spinner. The current approach seems to extend spinner to make more specialized versions. Although not in the current release, development on the timepicker includes a spinner to allow stepping through each part of the time value (hours, minutes, seconds). The same theme can be used to add extra visual controls to the spinner to provide alternative ways of selecting values.

Enforcing certain values in the field is a little bit more challenging. The primary design goal of the Spinner is to provide globalized formatting of numbers, etc. That validation is deferred to the Globalize library. For different formats, different values are allowable. Another widget in development right now - Mask - provides a means to add validation to any field. Combine a mask with the spinner and you get incremental stepping with the spin controls and enforcement of manually input numbers that agree with the selected locale.

I created an example that combines a slider and spinner. The code is not too complicated, however, you can see there is some work to ensure all the visual components stay in sync. Additionally, the demo uses the alternative layout enhancements I made to the spinner.

Keeping with the example set in the demos and development of jQuery UI, I created an extension to encapsulate the code required to draw and coordinate the spinner and slider controls. I called it SlideSpinner and you can see how it works on the project page. The implementation does not address restricting manually entered values. I did make an attempt, but to keep it generic enough to work with different locales, requires a lot more effort so it does not interfere with the users typing. However, I was able to get a feel for how to extend the functionality of a base widget to provided enhanced features like adding the slider. The SlideSpinner handles all the details of drawing the two widgets, positioning them, and then maintaining the values when the user interacts with either widget.

The jQuery UI library provides an excellent starting point for building customized widgets for more specific situations. Instead of bloating the Spinner widget with features that may only be useful in certain applications, it provides the basic framework to enable incremental controls that can be easily extended to create more specific enhancements as required. As long as the library includes appropriate hooks to build these extensions, then the available feature set is adequate to allow these new widgets to be constructed. As the library continues to mature, you can see that there will be a lot of extensible components that can be combined in specific ways to perform special tasks. Depending on the circumstances, you may need to build new widgets that extend the library or just combine the existing basic widgets in creative ways to build your solution.