Search code examples
javascripthtmlregexinputcheckvalidity

Input type password validity patternMismatch status is different to regex test result


I have a regex to check whether a string contains at least one digit, one lower case, and one upper case character.

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])

This evaluates to true with test strings such as '1aA'.

However the validity status of the patternMismatch does not evaluate in the same fashion as the regex test on the input elements value.

Is there a reason why the patternMismatch of an input would validate different to the regex test?

In the below snippet a class with associated background colour will be toggled depending on the result of the regex test. The invalid pseudo class should be true depending on the patternMismatch according to the MDN docs.

const password = document.getElementById("auth_user_password");

password.addEventListener("input", check);

function check() {
  /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/.test(password.value)
    ? password.classList.add("valid")
    : password.classList.remove("valid");
}
:focus {
  outline: none;
}

input:invalid {
  border: 3px solid red;
}

.valid {
  background-color: green;
}
<input id="auth_user_password" type="password" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])">


Solution

  • you need to set minimum charaters, then check it with element.validity.valid

    const password = document.getElementById("auth_user_password");
    
    password.addEventListener("input", check);
    
    function check() {
      password.validity.valid ?
        password.classList.add("valid") :
        password.classList.remove("valid");
    }
    input:invalid {border: 3px solid red;}
    .valid {background-color: green;}
    <input id="auth_user_password" name="password" type="text" autocomplete="off" pattern="(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])[a-zA-Z0-9]{6,}" value="" placeholder="min 6 chars">