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'))) { node[0].setCustomValidity(''); } 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 😉