Reputation: 9
So I've been making a password validator that will display feedback on the password a user is making based on the criteria.
HTML:
password: <input type="password" id="password" name="password"> <br>
<input type="checkbox" id="passwordReveal">
<label for="passwordReveal">Show Password</label>
<p id="feedback"></p>
What I am currently stuck on is how to make all of the error messages display as those criterias are not met, instead of only one error message at a time until all criteria is met.
Upvotes: 1
Views: 96
Reputation: 2297
I'd recommend you show password criteria explicitly and constantly show whether they're met, rather than providing feedback only when it's not met. See this Codepen link as a reference. Also, rather than use regex.test(string)
, I'd propose string.match(regex)
here to avoid inaccurate toggling.
// Password criteria
const CRITERIA_LOWERCASE = /[a-z]/g;
const CRITERIA_UPPERCASE = /[A-Z]/g;
const CRITERIA_NUMBERS = /[0-9]/g;
const CRITERIA_SPECIALS = /[^A-z\s\d][\\\^]?/g;
const CRITERIA_LENGTH = 6;
// DOM elements: password feedback
const pwLength = document.querySelector('li.pw-length');
const pwLowercase = document.querySelector('li.pw-lowercase');
const pwUppercase = document.querySelector('li.pw-uppercase');
const pwNumber = document.querySelector('li.pw-number');
const pwSpecial = document.querySelector('li.pw-special');
// DOM elements: inputs
const toggle = document.querySelector('#toggle');
const passwordField = document.querySelector('#password');
toggle.addEventListener('change', () => {
passwordField.type === 'password' ? passwordField.type = 'text' : passwordField.type = 'password'
})
passwordField.addEventListener('keyup', validatePassword);
function validatePassword() {
const password = passwordField.value;
password.length >= CRITERIA_LENGTH ?
pwLength.classList.add('pass') :
pwLength.classList.remove('pass');
password.match(CRITERIA_LOWERCASE) ?
pwLowercase.classList.add('pass') :
pwLowercase.classList.remove('pass');
password.match(CRITERIA_UPPERCASE) ?
pwUppercase.classList.add('pass') :
pwUppercase.classList.remove('pass');
password.match(CRITERIA_NUMBERS) ?
pwNumber.classList.add('pass') :
pwNumber.classList.remove('pass');
password.match(CRITERIA_SPECIALS) ?
pwSpecial.classList.add('pass') :
pwSpecial.classList.remove('pass');
}
*, * > * {
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
width: 300px;
display: flex;
flex-direction: column;
align-items: center;
font-family: sans-serif;
box-shadow: 0 1px 10px rgba(0,0,0,.2);
}
.passwordBox {
width: 100%;
line-height: 2;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.feedback {
font-size: small;
padding: 20px;
width: 100%;
background-color: #eee;
}
.feedback ul {
list-style: none;
padding: 0;
margin: 10px 0 0;
}
.feedback li::before {
content: '🚫';
}
.feedback li.pass::before {
content: '🟢';
}
<div class="wrapper">
<div class="passwordBox">
<label for="password">
Password:
<input type="password" id="password" name="password">
</label>
<label for="toggle">
Show password
<input type="checkbox" id="toggle" name="toggle">
</label>
</div>
<div class="feedback">
<strong>
Password requirements
</strong>
<ul>
<li class="pw-length">
Minimum 6 characters
</li>
<li class="pw-lowercase">
At least 1 lowercase letter
</li>
<li class="pw-uppercase">
At least 1 uppercase letter
</li>
<li class="pw-number">
At least 1 number
</li>
<li class="pw-special">
At least 1 special character
</li>
</ul>
</div>
</div>
Upvotes: 0
Reputation: 20731
Maybe something like the following where you cummulate the messages in a variable and save the results in the DOM at the end?
var feedback = ""
if (password.length < passwordLength) {
feedback += "Password is too short<br/>";
} else if (!lowerCaseLetters.test(password)) {
feedback += "Does not contain a lower case letter<br/>";
} else if (!upperCaseLetters.test(password)) {
feedback += "Does not contain an upper case letter<br/>";
} else if (!numbers.test(password)) {
feedback += "Does not contain a number<br/>";
} else if (!specials.test(password)) {
feedback += "Does not contain a special character<br/>";
}
if(feedback.length == 0) {
feedback = 'password is valid'
}
feedbackElement.innerHTML = feedback;
Upvotes: 1