0

I am trying to validate a password input field with minimum length of 8 characters and must contain at least 1 uppercase, 1 lowercase, 1 digit, and 1 special character. [If the password is valid, the label becomes green. If it's not valid the label becomes red.]

I think I got the minimum length part, but I'm not sure if I'm implementing my Javacsript correctly for the other requirements.

function green() {
  var pw = document.getElementById('password').value;
  var pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$";
  if (pw.value == pattern) {
    document.getElementById('pw').style.color = "Green";
    document.getElementById('pw').innerHTML = "Password: &#10004";
  } else {
    document.getElementById('pw').style.color = "Black";
    document.getElementById('pw').innerHTML = "Password:";
  }
}
<label id="pw" for="password">Password:</label>
<input id="password" name="password" minlength="8" maxlength="50" class="form-control" type="password" onkeyup="green()" value="" />
Anna Nguyen
  • 33
  • 1
  • 11

2 Answers2

0

Your pattern is OK, but you need to consistently select the elements' and their properties, and call the appropriate methods on the appropriate variables:

var pw = document.getElementById('password').value;

will put the value (string) into the pw variable, so

if (pw.value == pattern) {

doesn't make sense - strings don't have a .value property.

To define a regular expression object, use / syntax, for example

var pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;

not string syntax (" delimiters), else you'll just have a string.

To test if a string passes a regular expression, you can call .test on the regular expression, passing the string you want to test.

The string you assign to style.color should be lowercased, not title-cased:

function green() {
  var pwText = document.getElementById('password').value;
  var pwElm = document.getElementById('pw');
  var pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
  if (pattern.test(pwText)) {
    pw.style.color = "green";
    pw.innerHTML = "Password: &#10004";
  } else {
    pw.style.color = "black";
    pw.innerHTML = "Password:";
  }
}
<label id="pw" for="password">Password:</label>
<input id="password" name="password" minlength="8" maxlength="50" class="form-control" type="password" onkeyup="green()" value="" />

Also, you might consider making it clear to the user that the inputted password is not sufficient, perhaps color the element red when it's not good enough:

function green() {
  var pwText = document.getElementById('password').value;
  var pwElm = document.getElementById('pw');
  var pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
  if (pattern.test(pwText)) {
    pw.style.color = "green";
    pw.textContent = "Password: ✔";
  } else {
    pw.style.color = "red";
    pw.textContent = "Password: ❌";
  }
}
<label id="pw" for="password">Password:</label>
<input id="password" name="password" minlength="8" maxlength="50" class="form-control" type="password" onkeyup="green()" value="" />
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

I've never been good at reading/writing regex. I rather go with having the different type of characters in different strings. This is alot more code than with regex, but readability should be okayish.

function green() {
    var password = document.getElementById('password').value;

    var lowercase = 'abcdefgh.....xyz';
    var uppercase = 'ABCDEFGH.....XYZ';
    var digit = '1234567890';
    var special = '§!"#¤%&/()=?@£$€{[]}+.....,<>;:_';

    var valid = true;

    if (!containsValidCharacter(password, lowercase)) {
        valid = false;
    }

    if (!containsValidCharacter(password, uppercase)) {
        valid = false;        }

    if (!containsValidCharacter(password, special)) {
        valid = false;
    }

    if (!containsValidCharacter(password, digit)) {
        valid = false;
    }

    if (password.length < 8) {
        valid = false;
    }

    if (valid) {
        document.getElementById('pw').style.color = "Green";
        document.getElementById('pw').innerHTML = "Password: &#10004";
    } else {
        document.getElementById('pw').style.color = "Black";
        document.getElementById('pw').innerHTML = "Password:";
    }
}

function containsValidCharacter(stringToTest, validCharacters) {
    for (var i = 0; i < stringToTest.length; i++) {
        if (validCharacters.indexOf(stringToTest.charAt(i)) !== -1) {
            return true;
        }
    }
    return false;
}

I am pretty sure that there is a neat way of simplifying that function. Good luck.

Magnus
  • 79
  • 7