Reputation: 1220
I have a password strength bar which which uses li
items which are styled with different colours to indicate to the user how strong their password is, like so:
<input type="password" name="password" id="password" placeholder="Password">
<ul id="passwordStrength">
<li class="point-reg"></li>
<li class="point-reg"></li>
<li class="point-reg"></li>
<li class="point-reg"></li>
</ul>
When a regEx criteria has been met through a set of if
statements, the counter
is incremented and a switch
statement then adds the necessary CSS background
property to each li
item depending on the counter
value.
var password_li = $('#passwordStrength').find('li');
var counter = 0;
if(pw.match(/[A-Z]/) && pw.match(/[a-z]/)) {
counter++;
}
//further regex if statements
switch(counter) { //patrick
case 0:
break;
case 1:
$(password_li[0]).css('background', '#e30613'); //first li
break;
case 2:
$(password_li[0]).css('background', '#e30613'); //first li
$(password_li[1]).css('background', '#f9b233'); //second li
break;
case 3:
$(password_li[0]).css('background', '#e30613'); //first li
$(password_li[1]).css('background', '#f9b233'); //second li
$(password_li[2]).css('background', '#53ab58'); //third li
break;
case 4:
$(password_li[0]).css('background', '#e30613'); //first li
$(password_li[1]).css('background', '#f9b233'); //second li
$(password_li[2]).css('background', '#53ab58'); //third li
$(password_li[3]).css('background', '#418746'); //fourth li
break;
}
This doesn't seem the most efficient way of styling the li
items. Also, if the user then deletes the value they have entered, the li
items remain the colour they have been assigned, rather than reverting back to their default colour of grey, which makes sense as there isn't a function in place to remove the styling. I can add grey to the li
items depending on what case
has been met in the switch
statement like so:
case 1:
$(password_li[0]).css('background', '#e30613');
$(password_li[1]).css('background', '#dcdcdc');
$(password_li[2]).css('background', '#dcdcdc');
$(password_li[3]).css('background', '#dcdcdc');
break;
But again, this does not seem the most efficient apporach.
Question
How do I approach this functionality so the styling for the li
elements can be dynamically added and removed?
Here is a JSFiddle
Upvotes: 2
Views: 643
Reputation: 133453
I would recommend adding/removing CSS classes rather than manipulating CSS rules.
You can persist which class to be add along with <li>
element using custom data-*
prefixed attribute.
Then you can target the elements on which classes needs to added using .filter()
method and :lt()
selector.
$(document).ready(function() {
var password_li = $('#passwordStrength').find('li');
$('#password').bind('keyup', function() {
var counter = 0;
var pw = $(this).val();
if (pw.length >= 8) {
counter++;
}
if (pw.match(/\d/)) { //match digit
counter++;
}
if (pw.match(/[A-Z]/) && pw.match(/[a-z]/)) { //match digit
counter++;
}
if (pw.match(/[$@$!%*#?&]/)) { //match digit
counter++;
}
//Get all classes to remove
var clssesToRemove = password_li.map(function() {
return $(this).data('matched-class');
}).get().join(' ');
//Remove all class
password_li.removeClass(clssesToRemove);
//Filter and add class
password_li.filter(':lt(' + counter + ')').each(function() {
$(this).addClass($(this).data('matched-class'));
});
})
})
ul#strength {
display: inline;
list-style: none;
padding: 0;
vertical-align: 2px;
}
.point-reg {
background: #DDD;
border-radius: 2px;
display: inline-block;
height: 10px;
margin-right: 2px;
width: 30px;
}
.first {
background-color: #e30613;
}
.second {
background-color: #f9b233;
}
.third {
background-color: #53ab58;
}
.fourth {
background-color: #418746;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row">
<div class="col-xl-8 offset-xl-2">
<div class="form-group row">
<div class="col-md-12">
<input type="password" name="password" class="form-control pill-radius font-body" id="password" placeholder="Password">
</div>
<div class="form-group row">
<div class="col-md-12">
<ul id="passwordStrength">
<li class="point-reg" data-matched-class="first"></li>
<li class="point-reg" data-matched-class="second"></li>
<li class="point-reg" data-matched-class="third"></li>
<li class="point-reg" data-matched-class="fourth"></li>
</ul>
</div>
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 11815
First, there's actually a method to remove the styling. Simply set it to nothing:
$(password_li[0]).css({
background: ""
});
// I guess that can be done inline too
$(password_li[0]).css("background", "");
But if you prefer to do it with less iterations, you can do it with CSS classes. Just set your parent element a class and the class will have a nth-child
selector that will set the color of each child, individually, depending on their position.
<style>
.list1 > li:nth-child(1) {
background: #e30613;
}
.list2 > li:nth-child(2) {
background: #f9b233;
}
.list3 > li:nth-child(3) {
background: #53ab58;
}
.list4 > li:nth-child(4) {
background: #418746;
}
.list5 > li:nth-child(5) {
background: red;
}
.list6 > li:nth-child(6) {
background: blue;
}
</style>
<input type="password" name="password" id="password" placeholder="Password">
<ul id="passwordStrength">
<li class="point-reg"></li>
<li class="point-reg"></li>
<li class="point-reg"></li>
<li class="point-reg"></li>
</ul>
Then you can add the classes to the parent depending on the counter, like this
counter && $("#passwordStrength").addClass("list" + counter);
And remove them when not needed
while(counter) {
$("#passwordStrength").removeClass("list" + counter--);
}
This way you can have the styles in other file, as recommended, instead of using inline styling, which is discouraged.
Fiddle: https://jsfiddle.net/b6jfgyvy/
Upvotes: 2
Reputation: 1740
Maybe you can do something like this
colours = [
'#e30613',
'#f9b233',
'#53ab58',
'#53ab58'
];
for (i = 0; i < counter; i++) {
$("password_li[" + i + "]").css('background', colours[i]);
}
You can reset all colours by:
$("password_li").css('background', '#dcdcdc');
Upvotes: 0