type: widget
realease: planned for 1.9
status: in development
documentation: http://docs.jquery.com/UI/Spinner
demo: http://view.jqueryui.com/master/demos/spinner/default.html
TODOs
1 - Description:
A spinner (stepper) is a simple widget that allows users to increment or decrement the current text box value without having to input it manually. Increments do not have to be whole numbers -- it could be set to decimal values (0.1) or large increments (5) for each step. For a detailed discussion of Spinner behavior, please read:
Apple Human Interface Guidelines: Stepper (Little Arrows)
MSDN UI Guidelines: Spin Controls
Proposed features:
- the input box may have multiple focus points and essentially be several spinners combined into one. Example: instead of using three separate spinners for hours/minutes/seconds, the input can contain all three (hh:mm:ss) and the user can focus on/change one segment at a time: http://www.filamentgroup.com/examples/timepicker/
- we should consider building masked input features into editable spinners to help ensure valid entries: http://digitalbush.com/projects/masked-in
- support spinning via drag. This could be achieved by adding a small divider between the spinner buttons. This will allow the user to press and drag the divider up/down to change the spinner value. We could also spin according to speed of drag? This is a good example of spinning via drag: http://members.upc.nl/j.chim/ext/spinner2/ext-spinner.html
Spinners are frequently used in a situation where there is a 'masked input' which essentially breaks what looks like a single text into multiple regions or zones that may have custom formatting or constraints. Although this is not technically part of the core spinner control, it needs to be considered by the developer so it will work in this situation. A good example of this is a time picker which has 3 zones that are all controlled by a single spinner. See a working example (recommended by Filament Group) here:
http://www.filamentgroup.com/examples/timepicker/
An example of good keyboard interaction with support for other formats such as date and time:
http://members.upc.nl/j.chim/ext/spinner2/ext-spinner.html
2 - Visual Design:

3 - Functional Specifications/Requirements:
A spinner is useful not only as a self standing widget but also as an integrated part of more complex widgets such as colorpickers, timepickers and datepickers. Hence the spinner should be made as extensible as possible and flexible enough to merge seamlessly into other widgets.
When the spinner is not read only, the user may enter a value via the text field that causes an invalid value (below min, above max, step mismatch, non-numeric input). Whenever a step is taken, either programmatically or via the step buttons, the value will be forced to a valid value (see the description for stepUp() and stepDown() for more details).
The advanced spinner will use menu for dropdowns and slider for the scrubber.
In theory, the spinner should support ranges from -Number.MAX_VALUE to Number.MAX_VALUE. However, because numbers lose integer precision at 2^53, our rounding fails when (max || val) - (min || 0) > 2^53, preventing the user from stepping. If someone can provide a working BigNumber implementation, we should be able to support the full range.
Options:
- culture (string, default: null)
- only used when the numberFormat option is set
- sets the culture to use for parsing and formatting the value
- if null, the currently set culture in Globalization is used
- see Globalization docs for available cultures
- incremental (various, default: true)
- controls the number of steps taken when holding down a spin button.
- a boolean
- when set to true, the stepping delta will increase when spun incessantly
- when set to false, all steps are equal (as defined by the step option)
- a function
- receives the number of spins that have occurred as a parameter
- must return the number of steps that should occur for the current spin
- max (number, default: null)
- maximum value allowed
- element's max attribute used if exists and the option is not explicitly set
- can be passed as string which will be parsed based on numberFormat and culture or just using native parseFloat
- if null, there is no maximum enforced
- min (number, default: null)
- minimum value allowed
- element's min attribute used if exists and the option is not explicitly set
- can be passed as string which will be parsed based on numberFormat and culture or just using native parseFloat
- if null, there is no minimum enforced
- numberFormat (string, default: null)
- format of numbers passed to the Globalization plugin, if available
- see Globalization docs for different formats, most common:
- n: decimal number
- C: currency
- page (number, default: 10)
- number of steps to take when paging via the pageUp()/pageDown() methods
- step (number, default: 1)
- size of step to take when spinning via buttons or via the stepUp()/stepDown() methods
- element's step attribute used if exists and the option is not explicitly set
- can be passed as string which will be parsed based on numberFormat and culture or just using native parseFloat
Callbacks (listed in sequence):
- start (event name: spinstart)
- original event types: mousedown, keydown
- triggered before a spin.
- cancelable and prevents spin, stop and change from firing if canceled.
- spin (event name: spin)
- original event types: mousedown, keydown
- triggered during increment/decrement (to determine direction of spin compare current value with ui.value).
- cancelable - if canceled, the value is not changed to ui.value, stop fires, and change fires if appropriate.
- stop (event name: spinstop)
- original event types: mouseup, keyup
- triggered after a spin.
- change (event name: spinchange)
- original event types: click, keyup, blur
- triggered when the value of the spinner has changed and the input is no longer focused.
Methods:
- pageDown([pages])
- decrements the value by the specified number of pages, as defined by the page-option.
- the pages parameter defaults to 1.
- follows same rules as stepDown().
- pageUp([pages])
- increments the value by the specified number of pages, as defined by the page-option.
- the pages parameter defaults to 1.
- follows same rules as stepUp().
- stepDown([steps])
- decrements the value by the specified number of steps.
- the steps parameter defaults to 1.
- if the resulting value is above the max or below the min, the value will be adjusted to the closest max or min.
- if the resulting value is a step mismatch, the value will be adjusted to the closest step.
- stepUp([steps])
- increments the value by the specified number of steps.
- the steps parameter defaults to 1.
- if the resulting value is above the max or below the min, the value will be adjusted to the closest max or min.
- if the resulting value is a step mismatch, the value will be adjusted to the closest step.
- value([value])
- getter/setter for the current value.
- if the value parameter is omitted, the method returns the current value.
- if the value parameter is provided, the method sets the spinner's value to the value provided.
- value can be a string, will be parsed based on numberFormat and culture options.
Keyboard:
- UP - increment with step size.
- DOWN - decrement with step size.
- PGUP - increment with page size.
- PGDN - decrement with page size.
- Focus should stay in the edit field, even after using the mouse to click one of the spin buttons.
ARIA
- The text field has a role of spinbutton
- The text field has aria-valuemin and aria-valuemax attributes set based on the min and max options
- The text field has aria-valuenow set as the value changes (constantly updated during spins)
Accessibility Notes
- JAWS doesn't announce the input as a spinbox, as it does for native controls on Windows, announces as spinbutton instead
- The DHTML style guide suggests making the right/left arrows increment/decrement the value as well, however this would make it difficult for a user to change the value of a multi-digit number manually via the text field.
4 - Markup & Style:
(only used prior to implementation)
5 - Latest version of plugin:
6 - Open issues being discussed
Comments (0)
You don't have permission to comment on this page.