JSH5F – A Javascript method to enable HTML5 Form Elements in Browsers which support them
In a continuation of my recent investigations into HTML5, I have been looking at HTML5 forms (sometimes referred to as Web Forms 2). HTML5 offers (currently) 13 completely new input types for forms (there are also some changes to several existing input elements), some of which look like they will be really useful:
search (for search forms)
number
range (a numeric range)
color
tel
(telephone number)url
email
date (date only, no time)
month (Jan, Feb etc.)
week (week of year)
time
(timestamp)datetime
(absolute date/times)datetime-local
(local date/times)The problem is, at the time of writing virtually no Browsers support these new input types (the only one I have on my Mac which supports them is Opera 10.10) and it’s going to be quite some time before we can even begin to think about relying on Browser support. But, I can’t imagine it will be long until Mozilla/Firefox and Webkit/Safari/Chrome add support. That got me thinking, it’s a shame we can’t make some use of the new HTML5 input types now…
So, I did a little investigatory work and by borrowing some excellent Javascript detection techniques (a really good article, in fact so good I don’t think there’s any point in me covering the same ground so if you;’re interested in the detection methods, I’d refer you to that article), I came up with a script which uses unobtrusive Javascript and W3C compliant HTML to convert standard type=”text” inputs to the new HTML5 input types! Hopefully this will be of some use to someone – please note that JavaScript is not exactly my forte, so if anyone who is reading is willing and able to contribute improvements to JSH5F, they will be gladly received!
NOTE: Since Browsers should default to type=”text” for any non-specified or mal-specified inputs, you could in theory just start using the new input types but this script offers you the chance to use the new HTML5 input types with a little less risk of unruly behaviour from older browsers and a simpler, cross-browser method of styling the HTML5 input types differently. I have also just updated the jsh5f.js JavaScript file to allow appending of a string to the name attribute of the input element (using the “name_suffix” variable near the top of the jsh5f.js script) – this important distinction allows you to very simply distinguish between converted and non-converted inputs which can be important as the new HTML5 input elements often supply data in a different format to a standard text input (see my post describing HTML5 input types and their data formats for more information).
JSH5F Examples
The script is really simple to use, you simply add a class of (by default) “h5f_input_NEW_INPUT_TYPE” to the class attribute of your input element. For example you could create the following markup which would convert a standard text input to an HTML5 date input:
<input type="text" class="textbox h5f_input_date" name="some_name" />
You can then ask the script to add further attributes to your converted HTML5 input element by adding (by default) “h5f{JSON_STYLE_STRING_OF_KEY/VALUE_PAIRS}” for example you could create the following markup which would convert a standard text input to an HTML5 range input:
<input type="text" class="textbox h5f_input_range h5f{min:-100,max:200,step:10}" name="some_name" />
Since your inputs will be transformed into HTML5 inputs on supporting browsers, you might want to style the converted HTML5 inputs a bit differently – You can do this by adding a CSS class which by default is prefixed with “h5fadd” for example if you want to add the CSS class “html5_range” to a range input you would create the following markup:
<input type="text" class="textbox h5f_input_range h5f_add_html5_range h5f{min:-100,max:200,step:10}" name="some_name" />
There is a simple working example of jsh5f.js here (Please note: as far as I know, JSH5F will currently only work on Opera 10 as only Opera 10 supports the necessary HTML5 for input types)
Notes:
- The class “textbox” has nothing to do with the JSH5F script, it’s just there as an example to show that you can have one or more CSS classnames on your input element which can be simply used to style the element in the standard way. Also, you can change the prefix strings for the input element type (default: “input_”) and config JSON prefix (default: “h5f”) in the jsh5f.js Javascript file.
- It is also worth mentioning that Browser support for attributes such as “required” and “placeholder” are event more scant than Browser support for the new HTML5 input element types – Wikipedia currently has a HTML5 features compatibility table which I am hoping will be maintained.
- Testing is a little tricky since only Opera appears to support any of the HTML5 input types but I have tested the script on FireFox (3.6 OSX), Safari (4 OSX) and Opera (10.10 OSX) and there are no reported errors – I will test on Internet Explorer Windows as soon as I can.
- jsh5f.js uses only standard JavaScript, it does not require (nor should it interfere with) any JavaScript libraries (MooTools, JQuery, Prototype etc)
Download
The code itself is hosted on Google code: Google Code Project jsh5f
A Brief troubleshooting guide
- Ensure that when adding extra attributes (using the h5f prefix), you use a different type of quotes (single/double) from that enclosing your class definition e.g.:
<input type="text" class="textbox input_range h5f{required="required"}" name="some_name" />
will fail because the class definition is ended by the first double-quote on the required=”required” – obvious when looking at HTML source code but not always obvious when looking at PHP or some other HTML generator code. You should instead user:
<input type="text" class='textbox input_range h5f{required="required"}' name="some_name" />
Strictly speaking, JSON string values should only ever be enclosed by double quotes (reference: http://www.json.org/)
- If you are using PHP to generate your extra attributes and you need a string with spaces in (e.g. for the placeholder attribute), you need to encode the string with rawurlencode() rather than urlencode() because the JavaScript function decodeURIComponent() only works with rawurlencode() strings.
- You should have no spaces at all in your h5f{OPTIONS} string, otherwise it will look like more than one “class”. You should not need any spaces in your “keys” and any spaces in values should be urlencoded (with rawurlencode in PHP or similar)
References and further reading:
- JavaScript detection of HTML5 features – Dive in to HTML5: http://diveintohtml5.org/detect.html
- JavaScript DOM compatibility table – Quirksmode.org: http://www.quirksmode.org/dom/w3c_core.html
- HTML5 specification draft – WhatWG: http://www.whatwg.org/specs/web-apps/current-work/multipage/
- HTML5 features support compatibility table – Wikipedia.org: http://en.wikipedia.org/wiki/Comparison_of_layoutengines%28HTML5%29