To do this, what you need is 1) the following Ext JS widget extends from
Ext.form.field.Text. 2) do not forget the CSS file and images used in CSS. To change the appearance of password meter, you can simply change images used in CSS. JavaScript code:
Ext.define('yiyu.util.PasswordMeter',
{
extend : 'Ext.form.field.Text',
alias : 'widget.passwordMeter',
inputType : 'password',
reset : function() {
this.callParent();
this.updateMeter(this);
},
//private
onRender : function(container, position) {
var me = this;
me.callParent(arguments);
this.objMeter = me.el.createChild({
tag : "div",
'class' : "strengthMeter"
});
me.objMeter.setWidth(me.el.getWidth(true) - 17);
me.scoreBar = me.objMeter.createChild({
tag : "div",
'class' : "scoreBar"
});
me.scoreBar.setWidth(me.objMeter.getWidth(true));
if (Ext.isIE6) { // Fix style for IE6
this.objMeter.setStyle('margin-left', '3px');
}
},
// private
initEvents : function() {
var me = this, el = me.inputEl;
me.callParent();
me.mon(el, {
scope : me,
keyup : me.updateMeter
});
},
/**
* Sets the width of the meter, based on the score
*
* @param {Object} e
* Private function
*/
updateMeter : function() {
var score, p, maxWidth, nScore, scoreWidth;
score = 0;
p = this.getValue();
maxWidth = this.objMeter.getWidth() - 2;
nScore = this.calcStrength(p);
scoreWidth = maxWidth - (maxWidth / 100) * nScore;
this.scoreBar.setWidth(scoreWidth, true);
},
/**
* Calculates the strength of a password
*
* @param {Object} p
* The password that needs to be calculated
* @return {int} intScore The strength score of the password
*/
calcStrength : function(p) {
var intScore = 0;
// PASSWORD LENGTH
intScore += p.length;
if (p.length > 0 && p.length <= 4) { // length 4 or
// less
intScore += p.length;
} else if (p.length >= 5 && p.length <= 7) {
// length between 5 and 7
intScore += 6;
} else if (p.length >= 8 && p.length <= 15) {
// length between 8 and 15
intScore += 12;
} else if (p.length >= 16) { // length 16 or more
intScore += 18;
}
// LETTERS (Not exactly implemented as dictacted above
// because of my limited understanding of Regex)
if (p.match(/[a-z]/)) {
// [verified] at least one lower case letter
intScore += 1;
}
if (p.match(/[A-Z]/)) { // [verified] at least one upper
// case letter
intScore += 5;
}
// NUMBERS
if (p.match(/\d/)) { // [verified] at least one
// number
intScore += 5;
}
if (p.match(new RegExp(".*\\d.*\\d.*\\d"))) {
// [verified] at least three numbers
intScore += 5;
}
// SPECIAL CHAR
if (p.match(new RegExp("[!,@,#,$,%,^,&,*,?,_,~]"))) {
// [verified] at least one special character
intScore += 5;
}
// [verified] at least two special characters
if (p.match(new RegExp(
".*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]"
))) {
intScore += 5;
}
// COMBOS
if (p.match(new RegExp("(?=.*[a-z])(?=.*[A-Z])"))) {
// [verified] both upper and lower case
intScore += 2;
}
if (p.match(new RegExp(
"(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])"))) {
// [verified] both letters and numbers
intScore += 2;
}
// [verified] letters, numbers, and special characters
if (p
.match(new RegExp(
"(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])"
))) {
intScore += 2;
}
var nRound = Math.round(intScore * 2);
if (nRound > 100) {
nRound = 100;
}
return nRound;
}
})
CSS code:
.strengthMeter {
border: 1px solid #B5B8C8;
margin: 3px 0 3px 0;
background-image: url(images/meter.gif);
height: 10px;
background-size: 100%;
}
.scoreBar {
background-image: url(images/meter_background.gif);
height: 10px;
background-size: 100%;
line-height: 1px;
font-size: 1px;
float: right;
}
Edit: Here is a better implementation crated by osnoek.
There is a small bug when using the flex parameter. Thanks.
ReplyDelete