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