37

I can't get the pattern attribute on a text input to be limited to numbers. According to the javascript regular expressions list, [d] or [0-9] should do it. But in

<input dir="ltr" type="text" title="Enter numbers only." pattern="[\d]{9}" id="uid" name="1" placeholder="Enter UID" required="'required'" class="required placeholder" minlength="9" maxlength="9" autocomplete="off" />

it doesn't work for me (in any browsers). I have to add js validation such as the following (decided to go this route for simplicity based on this post):

HTML:

onkeypress='return isNumberKey(event)' 

js:

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : event.keyCode
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

I mainly want to know if there's a way I can get the pattern attribute to work. But also feel free to comment on whether I'm using best practices route for this. I don't want to use HTML5 <input type="number"/> as it's not widely supported enough yet.

10
  • Have you tried using [0-9]{9} instead ? Commented Sep 28, 2013 at 12:01
  • what browser and version are you using? the pattern attribute is also html and supported only in the latest browsers (i.e. IE9 doesn't support it). Commented Sep 28, 2013 at 12:07
  • Seems to be working fine. I added a CSS check to give red when invalid and green when valid: jsfiddle. Commented Sep 28, 2013 at 12:11
  • 1
    The validation for the pattern attribute will not prevent adding incorrect information, but it will prevent submitting the form. You can also use the CSS selectors @Jerry used in his demo. Commented Sep 28, 2013 at 12:13
  • 1
    See this update of @Jerry's fiddle: jsfiddle.net/bHWcu/1 Commented Sep 28, 2013 at 12:14

3 Answers 3

69

The validation for the pattern attribute will not prevent writing incorrect information into the field, but it will prevent submitting the form. The element also has an oninvalid event that will be called when the validation fails during the submit.

Alternatively, you can also use the CSS selectors :valid and :invalid to provide instant visual feedback.

Fiddle showing both (based on Jerry's fiddle from the comments): http://jsfiddle.net/bHWcu/1/

<form onsubmit="alert('Submitted');">
    <input dir="ltr" type="text" title="Enter numbers only." pattern="[\d]{9}" id="uid" name="1" placeholder="Enter UID" required="'required'" class="required placeholder" maxlength="9" autocomplete="off" />
    <input type="submit" value="Submit" />
</form>

Note that any client-side validation should only be used for fast feedback to improve the user experience. The actual validation should always be done server-side, as the client-side validation can easily be cheated.

Sign up to request clarification or add additional context in comments.

8 Comments

Ah! Thank you. That was exactly my confusion: I thought the pattern attribute was supposed to disable the user from entering in invalid characters. Thanks everyone for the lightning fast feedback.
+1 Might also add that the square brackets are not required for the pattern :)
Actually preventing entering data can be a slippery slope anyway, and it can be somewhat annoying, too. For example, \d{9} being validated on every keystroke would prevent the user from ever entering anything other than all 9 digits at once (through copy-paste).
Drop minlength, it is pointless and invalid. The markup could also be simplified in a few ways. But the main point is that the code in the answer is basically the same as in the question, so a casual reader will not immediately see what the problem was and what the solution is.
@Leo {9} is short-hand for {9,9}.
|
8

The pattern attribute only prevents the form from being submitted if its value does not match. To actually prevent the user from entering invalid text, checkValidity() can be used.

Demo:

let prevVal = "";
document.querySelector('input').addEventListener('input', function(e){
  if(this.checkValidity()){
    prevVal = this.value;
  } else {
    this.value = prevVal;
  }
});
Only enter digits: <input pattern="[0-9]*">

1 Comment

Nice, thanks for pointing out checkValidity(). This looks to be super useful.
0

A revised version to Unmitigated's answer.

let prevVal = "";
document.addEventListener("DOMContentLoaded", function(){
//window.addEventListener('load',function(){
    document.querySelector('INPUT').addEventListener('input', function(e){
      if(this.checkValidity()){
        prevVal = this.value;
      } else {
        this.value = prevVal;
      }
    });    
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.