1

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.

asked Oct 22, 2021 at 2:46
2
  • 1
    do feedbackElement.innerHTML = "" first, then use += instead of = afterwards. Commented Oct 22, 2021 at 2:49
  • might be nicer to make all errors lowercase, then plop the errors into an array, then join them with and, then uppercase first char, either with js or CSS .. Password is too short and does not contain a lower case letter.. though generally, you would show just a single error message which tells the user concisely what to enter, i.e Password must be >= n characters in length and must contain at least one special character, upper and lower case characters Commented Oct 22, 2021 at 2:58

2 Answers 2

1

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;
answered Oct 22, 2021 at 2:54
Sign up to request clarification or add additional context in comments.

1 Comment

better if the feedbacks are stored in an array, so that the result feedback array can be easier to be formatted nicely (e.g. wrap it with unordered list)
0

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>

answered Oct 22, 2021 at 4:29

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.