What's New in HTML5 Forms: Handling Numeric Inputs
This article will focus on a couple of new HTML5 elements that facilitate the inputting of numeric data: the number and range input types. Both accomplish the same thing, albeit using slightly different User Interfaces (UI).
The Number Input Type
Where recognized, an input type with an attribute of "number" is rendered as a text field with a spinbox beside it for entering a number within a specific range. Browsers which do not support the "number" type will display the default textbox element - in other words, without the accompanying spinbox. The number input type can accept both positive and negative integers as well as floating point numbers.
There are three optional attributes that can be used to set some limits on the number element. The boundaries can be set using the min and max attributes, while the increments can be set using the step attribute. Here are some examples:
<form action="a_page.asp" method="get"> <label for="intNumber">An input that accepts an integer from 1 to 20 in increments of 1:</label> <input id="intNumber" type="number" min="1" max="20" /> <br> <br> <label for="floatNumber">An input that accepts a floating point number from 1 to 10 in .5 increments:</label> <input id="floatNumber" type="number" min="1" max="10" step="0.5" value="5" /> <br> <br> <label for="intNumberStep3">An input that accepts an integer from 10 to 50 in increments of 3:</label> <input id="intNumberStep3" type="number" min="10" max="50" step="3" value="10" required="true" /> <br> <br> <input type="submit" /> </form>
The first element accepts integers from one to twenty. Since the step attribute has not been included, it will use the default step interval of one. The second input will set a floating point value between one and twenty at intervals of 0.5. The last input was assigned a range of ten to fifty with a step of three. Although the maximum value of fifty is not attainable with a step of three, the browser will stop incrementing when the next value would be above fifty. Alternatively, the user may simply enter the number in the textbox.
Who Supports the Number Element Type?
At this time, the number element type is supported as of Chrome 13, Safari 5.1, Safari Mobile, Opera 11.5, and Internet Explorer Preview Platform 2. Firefox does not yet support it.
Quirks and Oddities
There are a few things that you should know before using the number input type. Like HTML markup in general, HTML5 form elements do no throw errors when there is invalid syntax or attribute values. This can allow you to do strange things like set the value to a number that is outside of the range or even in an unacceptable format, such as floating point where only integers are permitted. Stranger still, you can set the value to a text string which contains no numbers whatsoever.
Handling of Non-numeric Input
Since entering non-numeric data is easily done, this begs the question "how does the browser handle such invalid data?" Well, it depends on the browser and whether or not the field is mandatory. On a non-mandatory field, the browser parses its value and only retains valid characters, including digits, the minus sign(-) and period(.). On mandatory fields, which include the "required" attribute, the browser may display an error message - as in the case of Opera 11.5x - or simply parse out any non-valid characters - as is done by Safari 5.1:
Note that, in my tests of Windows Safari 5.1, the browser displayed the controls correctly and parsed out invalid characters, but displayed no validation messages, even when a required field contained no input!
var intNumberStep3 = document.getElementById("intNumberStep3"); intNumberStep3.setCustomValidity("Invalid value! Please try again.");
// increase value by n input.stepUp(n) // decrease value by n input.stepDown(n) // return value as number instead of string input.valueAsNumber()
The Range Input Type
Similar to the number type, the "range" input type sets a numeric value using a slider control. It's supposedly for "imprecise" numeric input, where the specific number chosen is not as important as the its general location on a scale. For that reason, the browser does not display the chosen value. Here is the code to convert the intNumber element above from a number to a range input type:
<label for="intNumber">An input that accepts an integer from 1 to 20 in increments of 1:</label> <input id="intNumber" type="range" min="1" max="20" />
The above code produces the following in Opera 11.51:
For greater control over the range input, you can add an <DIV> or readonly textbox to display the current value, or better still, the HTML5 output tag, whose purpose is to display the result of a calculation. In the following example, a range control is set with the default value of ten. The one-liner updateRangeValue() function sets the intNumberValue <output> to the intNumber control's starting value:
Now it's clear what the value is at all times, thus allowing for precise number inputting:
The Fallback Position
Its important to provide fallback for browsers that do not support HTML5 elements. The following code combines the two immensely popular Modernizr and jQuery JS libraries. It finds all range elements and uses their attributes to substitute the jQuery UI slider in their place:
As with all things HTML5, the question remains as to whether the time is right to include an API which is not yet fully supported by all browsers. Then again, is anything fully supported by all browser makes and versions? I say, as long as you've got a fallback position, go for it!