Legacy Support for HTML 5 Forms

As discussed in the article, HTML 5 Feature Detection Using Modernizr, HTML 5 contains many new input types and attributes. While, most new browsers support them (although often imperfectly), the majority of people still use browsers that do not. However, we can use JavaScript to provided legacy support for the new HTML 5 input attributes and types in browsers that lack support. Toadys article introduces a widget for the YUI 3 gallery, that emulates HTML 5, the Gallery HTML5 Forms module.

Getting ready

You need a form, that contains inputs using HTML 5 features (Test Page):

<form id="id_form_test"><ul>
        <li>
			<label for="id_autofocus">Autofocused field:</label>
			<input class="input" id="id_autofocus" autofocus />
        </li>
        <li>
			<label for="id_email">Email:</label>
			<input class="input" id="id_email" type="email" />
        </li>
        <li>
			<label for="id_max">Max field (10):</label>
			<input class="input" id="id_max" max="10" />
        </li>
        <li>
			<label for="id_min">Min field (10):</label>
			<input class="input" id="id_min" min="10" />
        </li>
        <li>
			<label for="id_pattern">Pattern (\d+\s\w+) [numberSpaceWord]:</label>
			<input class="input" id="id_pattern" pattern="\d+\s\w+" />
        </li>
        <li>
			<label for="id_placeholder">Placeholder:</label>
			<input class="input" id="id_placeholder" placeholder="The cake is a lie!" />
        </li>
        <li>
			<label for="id_required">Required:</label>
			<input class="input" id="id_required" required />
        </li>
        <li>
			<label for="id_url">Url:</label>
			<input class="input" id="id_url" type="url" />
        </li>
        <li>
			<label for="id_ta_placeholder">TextArea Placeholder:</label>
			<textarea cols="15" id="id_ta_placeholder" rows="5" placeholder="Dont fear the reaper"></textarea>
        </li>
        <li>
			<label for="id_ta_required">TextArea Required:</label>
			<textarea cols="15" id="id_ta_required" rows="5" required></textarea>
        </li>
        <li>
			<button type="submit">Submit</button>
        </li>
    </ul></form>

How to do it…

Include and use the module:

YUI({
    debug: true,
    filter : "raw",
	modules: {
		gallery-html5-forms: {
			fullpath: https://github.com/mattsnider/yui3-gallery/raw/master/build/gallery-html5-forms/gallery-html5-forms.js,
			requires: [base, widget, node, gallery-modernizr],
			optional: [json]
		}
	}
}).use(gallery-html5-forms, function(Y) {
	function aftervalidationfx(elNode, boolValid) {
		// do something after a field validates or not
	}

	var html5Form = new Y.HTML5FormSupport({boundingBox: #id_form_test, aftervalidationfx: aftervalidationfx});
	html5Form.render();
});

Include the following CSS to style input validation and placeholder text:

input.placeholder {
	color: #999;
}

textarea:invalid,
textarea.invalid,
input:invalid,
input.invalid {
	border-color: #900;
}

textarea:valid,
textarea.valid,
input:valid,
input.valid {
	border-color: #090;
}

How it works…

I wont got into the specifics of how the code emulates HTML 5, but you can check it out, here. The rest of this article explains how the utility is expected to work.

First the module detects if the browser supports HTML 5 features using the Modernizr gallery module. By default, browsers that support HTML 5 do not use the HTML 5 Form module, unless you want to execute a custom function after blurring an input or in place of normal form submission. When an HTML 5 compliant browser is not detect, the module attaches events to all the editable input elements, which will be used to emulate HTML 5 features.

The HTML 5 Forms module iterates through all the inputs and textareas to look at their attributes. It currently supports the autofocus, min, max, pattern, placeholder, and required attributes, using the focus, blur, and keydown events to emulate the HTML 5 attributes. Additionally, the module supports validating the email and url input types, and this is achieved by leveraging the pattern attribute.

Although any element can be passed in as the boundingBox, there is special logic that is executed when a form element is provided. When a form is passed in as the boundingBox, the module will disable the submit button and form any time a field in the form is invalid, until such time as all fields are valid again.

When fields are validated, HTML 5 provides two new pseudo classes :invalid and :valid, which you can use to style element. The HTML 5 Form module uses the classes invalid and valid when emulating HTML 5 validation logic. These classes should be assigned the same styles as the HTML 5 pseudo classes in your CSS. Additionally, a placeholder class is used to apply the styles for the emulated placeholder text.

Lastly, the module adds several useful new features. First, if you need a function to fire anytime a field is validated, then provide a aftervalidationfx function. This function will be passed two arguments: the element being validated and a boolean indicated if it the field is valid. Secondly, if you want to submit the form via AJAX, then provide a submitfx function. This will prevent normal form submission and delegate form submission entirely to your callback function. Finally, you can specify the CSS rules to find the submit button by overwriting the submitbtn property. This will control what button is disabled when a field in the form is invalid.

Theres more…

Right now only input and textarea fields are managed through this module, but some HTML 5 properties work on other fields as well (such as select). This tool will eventually support more element and input types, and additional HTML 5 attributes.

The new number and range input types warrant further study. It is probably a good idea to use the YUI slider when emulating the range type, and a spinner widget when emulating number. However, adding these features will affect the performance of the code, so improvements like this will probably be added as plugins in the future.

Lastly, Ryan Seddon of The CSS Ninja did something similar, and you can check it out at http://www.thecssninja.com/javascript/h5f. Hes got some good ideas, such as using the event capture phase, that I may use to improve this module later. You may find this useful, if you dont use YUI for your project(s).