Back in action. |
Just recently, as part of a programming exercise, I was working on a Password Strength Validator. My idea here was for there to be a text field, and as the user types in a password, there is a label describing the input's password strength as Excellent, Good, Moderate or Weak. For this, I used jQuery to process everything.
It mostly went well. The function I created to determine the password strength did its job and returned the correct values - a password strength indicator (e.g., "Weak") and a more detailed message as to what was wrong with it (i.e, "Password is too short"). The CSS and styling were all fine. I tested it with sample input.
What went wrong
Oh, it looked like everything was wrong. The indicator failed to come on no matter what I typed.Here's the code. I won't go into detail with the getPasswordStrength() function. Suffice to say, the function worked as expected.
<!DOCTYPE html>
<html>
<head>
<title>Password Strength Validator</title>
<style>
.password
{
display:block;
width:20em;
}
.strength
{
font-size:2em;
font-weight:bold;
transition:all 1s;
}
.comments
{
font-size:1em;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function displayPasswordStrength(password)
{
if (password.length == 0)
{
$(".indicator.strength").html("");
$(".indicator.comments").html("");
}
else
{
var pwd_strength = getPasswordStrength(password);
$(".indicator.strength").html(pwd_strength.strength);
$(".indicator.comments").html(pwd_strength.comments);
if (pwd_strength.strength == "Excellent")
{
$(".indicator.strength").attr("style","color:#00FF00");
}
if (pwd_strength.strength == "Good")
{
$(".indicator.strength").attr("style","color:#FFFF00");
}
if (pwd_strength.strength == "Moderate")
{
$(".indicator.strength").attr("style","color:#FF4400");
}
if (pwd_strength.strength == "Weak")
{
$(".indicator.strength").attr("style","color:#440000");
}
}
};
function getPasswordStrength(password)
{
...
}
</script>
</head>
<body>
Password:
<input class="password" oninput="displayPasswordStrength(this.value)">
<div class="indicator">
<span class="strength">
</span>
<span class="comments">
</span>
</div>
</body>
</html>
<html>
<head>
<title>Password Strength Validator</title>
<style>
.password
{
display:block;
width:20em;
}
.strength
{
font-size:2em;
font-weight:bold;
transition:all 1s;
}
.comments
{
font-size:1em;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function displayPasswordStrength(password)
{
if (password.length == 0)
{
$(".indicator.strength").html("");
$(".indicator.comments").html("");
}
else
{
var pwd_strength = getPasswordStrength(password);
$(".indicator.strength").html(pwd_strength.strength);
$(".indicator.comments").html(pwd_strength.comments);
if (pwd_strength.strength == "Excellent")
{
$(".indicator.strength").attr("style","color:#00FF00");
}
if (pwd_strength.strength == "Good")
{
$(".indicator.strength").attr("style","color:#FFFF00");
}
if (pwd_strength.strength == "Moderate")
{
$(".indicator.strength").attr("style","color:#FF4400");
}
if (pwd_strength.strength == "Weak")
{
$(".indicator.strength").attr("style","color:#440000");
}
}
};
function getPasswordStrength(password)
{
...
}
</script>
</head>
<body>
Password:
<input class="password" oninput="displayPasswordStrength(this.value)">
<div class="indicator">
<span class="strength">
</span>
<span class="comments">
</span>
</div>
</body>
</html>
Why it went wrong
As mentioned, the function was working, and firing off upon input. But nothing was being changed on the front-end!
And when I finally found it, I had such a good laugh.
$(".indicator .strength").html(pwd_strength.strength);
$(".indicator .comments").html(pwd_strength.comments);
$(".indicator .comments").html(pwd_strength.comments);
This basically means that the element with the class strength within the indicator div was supposed to reflect the strength property of the passwordStrength object returned by the getPasswordStrength() function, and the element with the class comments would display the comments property.
But look closely at the selector on the first line. It was instead looking for an element with both the CSS classes strength and indicator! Same for the next line - looking for an element with both the CSS classes comments and indicator. And came up short.
How I fixed it
I could have just started using ids instead of classes, but really, that would be complicating what was essentially a very simple fix. Just add spaces where they're supposed to go.
<!DOCTYPE html>
<html>
<head>
<title>Password Strength Validator</title>
<style>
.password
{
display:block;
width:20em;
}
.strength
{
font-size:2em;
font-weight:bold;
transition:all 1s;
}
.comments
{
font-size:1em;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function displayPasswordStrength(password)
{
if (password.length == 0)
{
$(".indicator .strength").html("");
$(".indicator .comments").html("");
}
else
{
var pwd_strength = getPasswordStrength(password);
$(".indicator .strength").html(pwd_strength.strength);
$(".indicator .comments").html(pwd_strength.comments);
if (pwd_strength.strength == "Excellent")
{
$(".indicator .strength").attr("style","color:#00FF00");
}
if (pwd_strength.strength == "Good")
{
$(".indicator .strength").attr("style","color:#FFFF00");
}
if (pwd_strength.strength == "Moderate")
{
$(".indicator .strength").attr("style","color:#FF4400");
}
if (pwd_strength.strength == "Weak")
{
$(".indicator .strength").attr("style","color:#440000");
}
}
};
function getPasswordStrength(password)
{
...
}
</script>
</head>
<body>
Password:
<input class="password" oninput="displayPasswordStrength(this.value)">
<div class="indicator">
<span class="strength">
</span>
<span class="comments">
</span>
</div>
</body>
</html>
<html>
<head>
<title>Password Strength Validator</title>
<style>
.password
{
display:block;
width:20em;
}
.strength
{
font-size:2em;
font-weight:bold;
transition:all 1s;
}
.comments
{
font-size:1em;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function displayPasswordStrength(password)
{
if (password.length == 0)
{
$(".indicator .strength").html("");
$(".indicator .comments").html("");
}
else
{
var pwd_strength = getPasswordStrength(password);
$(".indicator .strength").html(pwd_strength.strength);
$(".indicator .comments").html(pwd_strength.comments);
if (pwd_strength.strength == "Excellent")
{
$(".indicator .strength").attr("style","color:#00FF00");
}
if (pwd_strength.strength == "Good")
{
$(".indicator .strength").attr("style","color:#FFFF00");
}
if (pwd_strength.strength == "Moderate")
{
$(".indicator .strength").attr("style","color:#FF4400");
}
if (pwd_strength.strength == "Weak")
{
$(".indicator .strength").attr("style","color:#440000");
}
}
};
function getPasswordStrength(password)
{
...
}
</script>
</head>
<body>
Password:
<input class="password" oninput="displayPasswordStrength(this.value)">
<div class="indicator">
<span class="strength">
</span>
<span class="comments">
</span>
</div>
</body>
</html>
Now it works!
Moral of the Story
jQuery is really neat and all, and selectors are easy to use. And also easy to get wrong if you're an idiot like me. This was not a syntax error, maybe not even a logic one. It was pretty much a typo. Oh, the horror. See how even a space can ruin your day?
Looks like another bug squashed. Excellent!
T___T
T___T