Larry Steinle

December 1, 2013

HTML5 Required and Pattern Attribute Fallback

Filed under: RegEx,Web — Larry Steinle @ 11:45 pm
Tags: , , , ,

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!

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: