Add Pattern Support for HTML5 Input Type Number with jQuery

Ran into an issue earlier today that I could not figure out and ended up asking my second question on StackOverflow in seven years.

I was trying to use <input type="number" pattern="[0-9]{8}"> to enforce 8-digit numbers while allowing leading zeros. This was being done on an optional field (no required attribute) and I could not understand why it was bypassing my pattern on the populated field (eg: value “1234” was accepted, pattern ignored).

Peter B. over at SO (kudos) pointed me to the MDN reference that provided the reason… number input does not support pattern attribute

By design! While their reasoning makes sense from a general perspective, the min/max attribute workaround does not help where leading zeros are acceptable (eg: min="00000001"is the same as min="1" for obvious reasons). Unfortunately I need all 8-digits for my purposes. I also tried using minlength and maxlength attributes as a hail-mary to no avail.

Here is a jQuery shim I wrote for my main script file thereby adding pattern support the <input type="number">

$('form').on('submit', function(){
    $('input[type="number"][pattern]', $(this)).each(function(){
        var node = $(this);
        var value = node.val();
        var pattern = node.attr('pattern');
        if (pattern && value) {
            if (value.match(new RegExp(pattern, 'g'))) {
            } else {
                node[0].setCustomValidity('Invalid pattern!');

We intercept the submit event of the form and loop through “number” fields with a “pattern” attribute. If pattern is not empty, the field has a value, and said pattern does not match,  I set the “Custom Validity” string triggering the browser’s built-in validation error routines. Likewise if the value matches the pattern, we remove any prior “invalid” messages.

Even though I am triggering my code on form.submit()  you can apply similar methods on a field-by-field basis to make it suit your needs (AJAX forms for instance).

I could have changed my input type to “text,” but prefer using HTML5 input types whenever possible for mobile UI benefits. Improves UX and limiting entry to numbers (eg: numeric keypad vs full keyboard) is exactly what I wanted.

This was the first real hiccup I’ve had with HTML5 input fields and client-side form validation. Hope they decide to make number fields support pattern in the future, but not going to hold my breath on that one 😛

Note: This particular project uses Bootstrap 4.1 with class="needs-validation" novalidate so I didn’t need to set a readable string in setCustomValidity, just anything non-empty. I chose to use ‘Invalid pattern!’ simply so I’d know why the heck I added that code down the road 😉

Leave a Reply

Your email address will not be published. Required fields are marked *