Continuing with the theme from the last article on an AutoFocus fallback, today we will learn how to support the Required and Pattern attributes.
The HTML5 required attribute specifies when an input, select or textarea tag must have a selected value before a page can be submitted. The pattern attribute allows the developer to provide a regular expression specifying when a tag’s value is in compliance with data rules. When the pattern fails to match the tag’s value the title attribute is displayed to the user.
Even on browsers that support the new required and pattern attributes there continues to be a need to manually support these attributes. Try making an AJAX call without a value in a tag that you specified as required. The code snippets below can easily be adapted to validate tags prior to making any AJAX calls.
The code in this article demonstrates how to provide backwards compatibility for the required and pattern attributes. Please note that HTML5 specifications state that the pattern attribute is supported only when the title tag is included.
Disable Event Bubbling
When any tag fails to meet the specified attribute requirements we will need to disable the submit event. The following routine provides a consistent means to disable the event regardless of browser type or version.
function DisableEvent(e) { if (e.returnValue) e.returnValue = false; if (e.cancelBubble) e.cancelBubble = true; if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
Required Attribute Fallback
Simply use a touch of jQuery to find the input, select and textarea tags that should be required checking each for a value. I like to add a css class called, required, to standardize styling when the required field has not been completed. Of course when a required field has been left unanswered we need to stop the post-back action.
$(document).ready(function () { function DisableEvent(e) { if (e.returnValue) e.returnValue = false; if (e.cancelBubble) e.cancelBubble = true; if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; } if (!("required" in document.createElement("input"))) { function getUnansweredTags() { /// <summary>Get list of required tags that haven't been answered.</summary> var tags = []; $("form").each("select[required], input[required], textarea[required]", function (i, c) { var $c = $(c); if (!$c.val()) tags.push($c); }); return tags; } $("form").on("submit", function (e) { var unanswered = getUnansweredTags(); $("select[required], input[required], textarea[required]").addClass("required"); if (unanswered.length > 0) { $(unanswered).addClass("required"); alert("Please complete the required fields"); return DisableEvent(e); } }); }
Pattern Attribute Fallback
A little more complicated than the required attribute, the pattern attribute uses a regular expression to identify when the supplied value is in compliance. Again I prefer to add a css class name of pattern to identify tags that fail to comply with the pattern. Additionally, I display the list of messages associated with each tag that is not in compliance.
$(document).ready(function () { function DisableEvent(e) { if (e.returnValue) e.returnValue = false; if (e.cancelBubble) e.cancelBubble = true; if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; } if (!("pattern" in document.createElement("input"))) { function getUnmatchedTags() { /// <summary>Get tags that fail the pattern match.</summary> var tags = []; $.each("input[pattern][title], textarea[pattern][title]", function (i, c) { var $c = $(c); var expEngine = new RegExp($c.attr("pattern")); if (!expEngine.test($c.val())) tags.push($c); }); return tags; } function getUnmatchedTitles() { /// <summary>Get the titles associated with the tags that fail the pattern match.</summary> var titles = []; $.each("input[pattern][title], textarea[pattern][title]", function (i, c) { titles.push($(c).attr("title")); }); return titles; } $("form").on("submit", function (e) { var unmatched = getUnmatchedTags(); $("input[pattern][title], textarea[pattern][title]").addClass("pattern"); if (unmatched.length > 0) { $(unmatched).addClass("pattern"); alert(getUnmatchedTitles().join("\r\n\r\n")); return DisableEvent(e); } }); } });
Summary
That’s all there is to it! Nothing too complicated. Just a nice, simple, useful code snippet.
Happy coding and Happy holidays!
Leave a Reply