From 1d93a21b7b599d5301fc4dded9b11d25c055a0d3 Mon Sep 17 00:00:00 2001 From: Misteregis Date: Tue, 18 Oct 2022 05:33:56 -0300 Subject: [PATCH 1/2] Improvements, fixes and localization --- css/jquery.passwordRequirements.css | 179 ++++++++------ js/jquery.passwordRequirements.js | 331 ++++++++++++-------------- js/jquery.passwordRequirements.min.js | 11 +- 3 files changed, 260 insertions(+), 261 deletions(-) diff --git a/css/jquery.passwordRequirements.css b/css/jquery.passwordRequirements.css index d894a1e..610e622 100644 --- a/css/jquery.passwordRequirements.css +++ b/css/jquery.passwordRequirements.css @@ -1,92 +1,115 @@ /* - * jQuery Minimun Password Requirements 1.1 + * jQuery Minimun Password Requirements 1.2 * http://elationbase.com * Copyright 2014, elationbase * Check Minimun Password Requirements * Free to use under the MIT license. * http://www.opensource.org/licenses/mit-license.php + * + * Modified by: Misteregis + * Modified date: 2022/10/18 */ -#pr-box { - font: 13px/16px sans-serif; - position: absolute; - z-index:1000; - display:none; - width:300px; - max-width:100%; -} -#pr-box i { - width: 0; - height: 0; + +.pr-box { + font: 13px/16px sans-serif; + position: absolute; + z-index: 1000; + display: none; + width: 300px; + max-width: 100%; + margin-top: 7px; +} + +.pr-box em { + width: 0; + height: 0; + display: block; margin-left: 20px; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #23a86d; } -#pr-box-inner { - margin-top: 6px; - -webkit-box-shadow: 0 2px 10px rgba(0,0,0,0.2); - -moz-box-shadow: 0 2px 10px rgba(0,0,0,0.2); - box-shadow: 0 2px 10px rgba(0,0,0,0.2); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -#pr-box p { - padding:20px; - -webkit-border-radius: 2px 2px 0 0; - -moz-border-radius: 2px 2px 0 0; - border-radius: 2px 2px 0 0; -} -#pr-box ul { - padding:7px; - -webkit-border-radius: 0 0 2px 2px; - -moz-border-radius: 0 0 2px 2px; - border-radius: 0 0 2px 2px; -} -#pr-box ul li { + +.pr-box-inner { + -webkit-box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} + +.pr-box p { + margin: 0; + padding: 20px; + -webkit-border-radius: 2px 2px 0 0; + -moz-border-radius: 2px 2px 0 0; + border-radius: 2px 2px 0 0; +} + +.pr-box ul { + padding: 7px; + -webkit-border-radius: 0 0 2px 2px; + -moz-border-radius: 0 0 2px 2px; + border-radius: 0 0 2px 2px; +} + +.pr-box ul li { list-style: none; - padding:7px; -} -#pr-box ul li span { - width:15px; - height:15px; - display:block; - float:left; - border-radius:100%; - margin-right:15px; -} -#pr-box.light { - color:#2d2f31; -} -#pr-box.light p { - background-color:#23a86d; - color:#f1f1f1; -} -#pr-box.light ul { - background-color:#f1f1f1; -} -#pr-box.light ul li span { - background-color:#f1f1f1; - border:3px solid #23a86d; -} -#pr-box.light ul li span.pr-ok { - background-color:#23a86d; - border:3px solid #23a86d; -} -#pr-box.dark { - color:#f1f1f1; -} -#pr-box.dark p { - background-color:#23a86d; -} -#pr-box.dark ul { - background-color:#2d2f31; -} -#pr-box.dark ul li span { - background-color:#2d2f31; - border:3px solid #23a86d; -} -#pr-box.dark ul li span.pr-ok { - background-color:#23a86d; - border:3px solid #23a86d; + padding: 7px; +} + +.pr-box ul li span { + width: 15px; + height: 15px; + display: block; + float: left; + border-radius: 100%; + margin-right: 15px; + transition: background-color 250ms ease-in-out; +} + +.pr-box.light { + color: #2d2f31; +} + +.pr-box.light p { + background-color: #23a86d; + color: #f1f1f1; +} + +.pr-box.light ul { + background-color: #f1f1f1; +} + +.pr-box.light ul li span { + background-color: #f1f1f1; + border: 3px solid #23a86d; +} + +.pr-box.light ul li span.pr-ok { + background-color: #23a86d; + border: 3px solid #23a86d; +} + +.pr-box.dark { + color: #f1f1f1; +} + +.pr-box.dark p { + background-color: #23a86d; +} + +.pr-box.dark ul { + background-color: #2d2f31; +} + +.pr-box.dark ul li span { + background-color: #2d2f31; + border: 3px solid #23a86d; +} + +.pr-box.dark ul li span.pr-ok { + background-color: #23a86d; + border: 3px solid #23a86d; } \ No newline at end of file diff --git a/js/jquery.passwordRequirements.js b/js/jquery.passwordRequirements.js index 79d9f72..14ef8b6 100644 --- a/js/jquery.passwordRequirements.js +++ b/js/jquery.passwordRequirements.js @@ -1,185 +1,170 @@ /* - * jQuery Minimun Password Requirements 1.1 + * jQuery Minimun Password Requirements 1.2 * http://elationbase.com * Copyright 2014, elationbase * Check Minimun Password Requirements * Free to use under the MIT license. * http://www.opensource.org/licenses/mit-license.php + * + * Modified by: Misteregis + * Modified date: 2022/10/18 */ - - -(function($){ - $.fn.extend({ - passwordRequirements: function(options) { - - // options for the plugin - var defaults = { - numCharacters: 8, - useLowercase: true, - useUppercase: true, - useNumbers: true, - useSpecial: true, - infoMessage: '', - style: "light", // Style Options light or dark - fadeTime:300 // FadeIn / FadeOut in milliseconds + + +(function ($) { + $.fn.passwordRequirements = function (options) { + // options for the plugin + options = $.extend($.fn.passwordRequirements.defaults, options); + + return this.each(function () { + + var o = options; + var $this = this; + + o.infoMessage = o.infoMessageText.replace('{0}', o.numCharacters); + + var lis = [], toCheck = {}; + + // Check if the options are true + $(['numCharacters', 'useLowercase', 'useUppercase', 'useNumbers', 'useSpecial']).each(function (_, opt) { + if (o[opt]) { + lis.push($('
  • ', { class: 'pr-' + opt, html: '' + o[opt + 'Text'] })); + toCheck[opt + 'Done'] = false; + } + }); + + if (!lis.length) return; + + var toCheckTotal = Object.keys(toCheck).length; + + var checked = function () { + return Object.values(toCheck).filter(b => b === true).length === toCheckTotal; + } + + // Show Message reusable function + var showMessage = function () { + if (!checked()) { + $(".pr-password").each(function () { + var id = 'pr-box-' + $(".pr-password").index($this); + + // Append info box to the body + if (!$("#" + id).length) { + var em = $(''); + var ul = $('
      ').append(lis); + var p = $('

      ', { text: o.infoMessage }); + var prBoxInner = $('

      ', { class: 'pr-box-inner' }).append([p, ul]); + var prBox = $('
      ', { id, class: 'pr-box' }).append([em, prBoxInner]); + + // Append input in the box + prBox.get(0)._element = $this; + + // Update box position + prBox.get(0).updatePos = function () { + var posH = $(this._element).offset().top, + itemH = $(this._element).innerHeight(), + top = posH + itemH, + left = $(this._element).offset().left; + + $(this).css({ top, left }); + }; + + $('.pr-box').remove(); + $("body").append(prBox); + + prBox.addClass(o.style) + .fadeIn(o.fadeTime) + .get(0).updatePos(); + + scroll({ top: $this.offsetTop, behavior: "smooth" }); + } + }); + } }; - options = $.extend(defaults, options); - - return this.each(function() { - - var o = options; - - o.infoMessage = 'The minimum password length is ' + o.numCharacters + ' characters and must contain at least 1 lowercase letter, 1 capital letter, 1 number, and 1 special character.'; - // Add Variables for the li elements - var numCharactersUI = '
    • # of characters
    • ', - useLowercaseUI = '', - useUppercaseUI = '', - useNumbersUI = '', - useSpecialUI = ''; - // Check if the options are checked - if (o.useLowercase === true) { - useLowercaseUI = '
    • Lowercase letter
    • '; - } - if (o.useUppercase === true) { - useUppercaseUI = '
    • Capital letter
    • '; - } - if (o.useNumbers === true) { - useNumbersUI = '
    • Number
    • '; - } - if (o.useSpecial === true) { - useSpecialUI = '
    • Special character
    • '; - } - - // Append password hint div - var messageDiv = '

      ' + o.infoMessage + '

        ' + numCharactersUI + useLowercaseUI + useUppercaseUI + useNumbersUI + useSpecialUI + '
      '; - - // Set campletion vatiables - var numCharactersDone = true, - useLowercaseDone = true, - useUppercaseDone = true, - useNumbersDone = true, - useSpecialDone = true; - - // Show Message reusable function - var showMessage = function () { - if (numCharactersDone === false || useLowercaseDone === false || useUppercaseDone === false || useNumbersDone === false || useSpecialDone === false) { - $(".pr-password").each(function() { - // Find the position of element - var posH = $(this).offset().top, - itemH = $(this).innerHeight(), - totalH = posH+itemH, - itemL = $(this).offset().left; - // Append info box tho the body - $("body") .append(messageDiv); - $("#pr-box") .addClass(o.style) - .fadeIn(o.fadeTime) - .css({top:totalH, left:itemL}); - }); - } - }; - - // Show password hint - $(this).on("focus",function (){ - showMessage(); - }); - - // Delete Message reusable function - var deleteMessage = function () { - var targetMessage = $("#pr-box"); - targetMessage.fadeOut(o.fadeTime, function(){ - $(this).remove(); - }); - }; - - // Show / Delete Message when completed requirements function - var checkCompleted = function () { - if (numCharactersDone === true && useLowercaseDone === true && useUppercaseDone === true && useNumbersDone === true && useSpecialDone === true) { - deleteMessage(); - } else { - showMessage(); - } - }; - - // Show password hint - $(this).on("blur",function (){ - deleteMessage(); - }); - - - // Show or Hide password hint based on user's event - // Set variables - var lowerCase = new RegExp('[a-z]'), - upperCase = new RegExp('[A-Z]'), - numbers = new RegExp('[0-9]'), - specialCharacter = new RegExp('[!,%,&,@,#,$,^,*,?,_,~]'); - - // Show or Hide password hint based on keyup - $(this).on("keyup focus", function (){ - var thisVal = $(this).val(); - - checkCompleted(); - - // Check # of characters - if ( thisVal.length >= o.numCharacters ) { - // console.log("good numCharacters"); - $(".pr-numCharacters span").addClass("pr-ok"); - numCharactersDone = true; - } else { - // console.log("bad numCharacters"); - $(".pr-numCharacters span").removeClass("pr-ok"); - numCharactersDone = false; - } - // lowerCase meet requirements - if (o.useLowercase === true) { - if ( thisVal.match(lowerCase) ) { - // console.log("good lowerCase"); - $(".pr-useLowercase span").addClass("pr-ok"); - useLowercaseDone = true; - } else { - // console.log("bad lowerCase"); - $(".pr-useLowercase span").removeClass("pr-ok"); - useLowercaseDone = false; - } - } - // upperCase meet requirements - if (o.useUppercase === true) { - if ( thisVal.match(upperCase) ) { - // console.log("good upperCase"); - $(".pr-useUppercase span").addClass("pr-ok"); - useUppercaseDone = true; - } else { - // console.log("bad upperCase"); - $(".pr-useUppercase span").removeClass("pr-ok"); - useUppercaseDone = false; - } - } - // upperCase meet requirements - if (o.useNumbers === true) { - if ( thisVal.match(numbers) ) { - // console.log("good numbers"); - $(".pr-useNumbers span").addClass("pr-ok"); - useNumbersDone = true; - } else { - // console.log("bad numbers"); - $(".pr-useNumbers span").removeClass("pr-ok"); - useNumbersDone = false; - } - } - // upperCase meet requirements - if (o.useSpecial === true) { - if ( thisVal.match(specialCharacter) ) { - // console.log("good specialCharacter"); - $(".pr-useSpecial span").addClass("pr-ok"); - useSpecialDone = true; - } else { - // console.log("bad specialCharacter"); - $(".pr-useSpecial span").removeClass("pr-ok"); - useSpecialDone = false; - } - } - }); + // Show password hint + $(this).on("focus", showMessage); + + // Delete Message reusable function + var deleteMessage = function () { + $(".pr-box").fadeOut(o.fadeTime, function () { + $(this).remove(); + }); + }; + + // Show / Delete Message when completed requirements function + var checkCompleted = function () { + if (checked()) { + deleteMessage(); + } else { + showMessage(); + } + }; + + // Show password hint + $(this).on("blur", deleteMessage); + + + // Show or Hide password hint based on user's event + // Set variables + var regex = { + numCharactersDone: function (val) { return val.length >= o.numCharacters }, + useLowercaseDone: function (val) { return val.match(/[a-z]/) !== null }, + useUppercaseDone: function (val) { return val.match(/[A-Z]/) !== null }, + useNumbersDone: function (val) { return val.match(/\d/) !== null }, + useSpecialDone: function (val) { return val.match(/[,!%&@#$^*?_~]/) !== null } + }; + + // Show or Hide password hint based on keyup (input) + $(this).on("input focus", function () { + checkCompleted(); + + for (var key in toCheck) { + var done = regex[key]($(this).val()); + var cls = done ? 'addClass' : 'removeClass'; + + toCheck[key] = done; + + $(".pr-" + key.slice(0, -4) + " span")[cls]("pr-ok"); + } }); - } + }); + }; + + $.fn.passwordRequirements.getPos = function (element) { + var posH = $(element).offset().top, + itemH = $(element).innerHeight(), + totalH = posH + itemH, + itemL = $(element).offset().left; + + return { top: totalH, left: itemL }; + } + + // plugin defaults + $.fn.passwordRequirements.defaults = { + numCharacters: 8, + useLowercase: true, + useUppercase: true, + useNumbers: true, + useSpecial: true, + infoMessage: '', + style: "light", // Style Options light or dark + fadeTime: 300 // FadeIn / FadeOut in milliseconds + }; + + $.fn.passwordRequirements.locales = []; + + $.fn.passwordRequirements.locales["en"] = { + infoMessageText: "The minimum password length is {0} characters and must contain at least 1 lowercase letter, 1 capital letter, 1 number, and 1 special character.", + numCharactersText: "# of characters", + useLowercaseText: "Lowercase letter", + useUppercaseText: "Capital letter", + useNumbersText: "Number", + useSpecialText: "Special character" + }; + + $.extend($.fn.passwordRequirements.defaults, $.fn.passwordRequirements.locales['en']); + + $(window).resize(function () { + $(".pr-box").get(0).updatePos(); }); })(jQuery); diff --git a/js/jquery.passwordRequirements.min.js b/js/jquery.passwordRequirements.min.js index 6cb2224..b80bf76 100644 --- a/js/jquery.passwordRequirements.min.js +++ b/js/jquery.passwordRequirements.min.js @@ -1,10 +1 @@ -/* - * jQuery Minimun Password Requirements 1.1 - * http://elationbase.com - * Copyright 2014, elationbase - * Check Minimun Password Requirements - * Free to use under the MIT license. - * http://www.opensource.org/licenses/mit-license.php -*/ - -(function($){$.fn.extend({passwordRequirements:function(options){var defaults={numcharacters:8,useLowercase:true,useUppercase:true,useNumbers:true,useSpecial:true,infoMessage:'',style:"light",fadeTime:300};options=$.extend(defaults,options);return this.each(function(){var o=options;o.infoMessage='The minimum password length is '+o.numcharacters+' characters and must contain at least 1 lowercase letter, 1 capital letter 1 number and 1 special character.'; var numcharactersUI='
    • # of characters
    • ',useLowercaseUI='',useUppercaseUI='',useNumbersUI='',useSpecialUI='';if(o.useLowercase===true){useLowercaseUI='
    • Lowercase letter
    • ';} if(o.useUppercase===true){useUppercaseUI='
    • Capital letter
    • ';} if(o.useNumbers===true){useNumbersUI='
    • Number
    • ';} if(o.useSpecial===true){useSpecialUI='
    • Special character
    • ';} var messageDiv='

      '+o.infoMessage+'

        '+numcharactersUI+useLowercaseUI+useUppercaseUI+useNumbersUI+useSpecialUI+'
      ';var numcharactersDone=true,useLowercaseDone=true,useUppercaseDone=true,useNumbersDone=true,useSpecialDone=true;var showMessage=function(){if(numcharactersDone===false||useLowercaseDone===false||useUppercaseDone===false||useNumbersDone===false||useSpecialDone===false){$(".pr-password").each(function(){var posH=$(this).offset().top,itemH=$(this).innerHeight(),totalH=posH+itemH,itemL=$(this).offset().left;$("body").append(messageDiv);$("#pr-box").addClass(o.style).fadeIn(o.fadeTime).css({top:totalH,left:itemL});});}};$(this).on("focus",function(){showMessage();});var deleteMessage=function(){var targetMessage=$("#pr-box");targetMessage.fadeOut(o.fadeTime,function(){$(this).remove();});};var checkCompleted=function(){if(numcharactersDone===true&&useLowercaseDone===true&&useUppercaseDone===true&&useNumbersDone===true&&useSpecialDone===true){deleteMessage();}else{showMessage();}};$(this).on("blur",function(){deleteMessage();});var lowerCase=new RegExp('[a-z]'),upperCase=new RegExp('[A-Z]'),numbers=new RegExp('[0-9]'),specialcharacter=new RegExp('[!,%,&,@,#,$,^,*,?,_,~]');$(this).on("keyup focus",function(){var thisVal=$(this).val();checkCompleted();if(thisVal.length>=o.numcharacters){$(".pr-numcharacters span").addClass("pr-ok");numcharactersDone=true;}else{$(".pr-numcharacters span").removeClass("pr-ok");numcharactersDone=false;} if(o.useLowercase===true){if(thisVal.match(lowerCase)){$(".pr-useLowercase span").addClass("pr-ok");useLowercaseDone=true;}else{$(".pr-useLowercase span").removeClass("pr-ok");useLowercaseDone=false;}} if(o.useUppercase===true){if(thisVal.match(upperCase)){$(".pr-useUppercase span").addClass("pr-ok");useUppercaseDone=true;}else{$(".pr-useUppercase span").removeClass("pr-ok");useUppercaseDone=false;}} if(o.useNumbers===true){if(thisVal.match(numbers)){$(".pr-useNumbers span").addClass("pr-ok");useNumbersDone=true;}else{$(".pr-useNumbers span").removeClass("pr-ok");useNumbersDone=false;}} if(o.useSpecial===true){if(thisVal.match(specialcharacter)){$(".pr-useSpecial span").addClass("pr-ok");useSpecialDone=true;}else{$(".pr-useSpecial span").removeClass("pr-ok");useSpecialDone=false;}}});});}});})(jQuery); \ No newline at end of file +(function(e){e.fn.passwordRequirements=function(s){return s=e.extend(e.fn.passwordRequirements.defaults,s),this.each(function(){var t=s,n=this;t.infoMessage=t.infoMessageText.replace("{0}",t.numCharacters);var a=[],r={};if(e(["numCharacters","useLowercase","useUppercase","useNumbers","useSpecial"]).each(function(s,n){t[n]&&(a.push(e("
    • ",{class:"pr-"+n,html:""+t[n+"Text"]})),r[n+"Done"]=!1)}),a.length){var o=Object.keys(r).length,u=function(){return Object.values(r).filter(e=>!0===e).length===o},i=function(){u()||e(".pr-password").each(function(){var s="pr-box-"+e(".pr-password").index(n);if(!e("#"+s).length){var r=e(""),o=e("
        ").append(a),u=e("

        ",{text:t.infoMessage}),i=e("

        ",{class:"pr-box-inner"}).append([u,o]),c=e("
        ",{id:s,class:"pr-box"}).append([r,i]);c.get(0)._element=n,c.get(0).updatePos=function(){var s=e(this._element).offset().top,t=e(this._element).innerHeight(),n=s+t,a=e(this._element).offset().left;e(this).css({top:n,left:a})},e(".pr-box").remove(),e("body").append(c),c.addClass(t.style).fadeIn(t.fadeTime).get(0).updatePos(),scroll({top:n.offsetTop,behavior:"smooth"})}})};e(this).on("focus",i);var c=function(){e(".pr-box").fadeOut(t.fadeTime,function(){e(this).remove()})},l=function(){u()?c():i()};e(this).on("blur",c);var p={numCharactersDone:function(e){return e.length>=t.numCharacters},useLowercaseDone:function(e){return null!==e.match(/[a-z]/)},useUppercaseDone:function(e){return null!==e.match(/[A-Z]/)},useNumbersDone:function(e){return null!==e.match(/\d/)},useSpecialDone:function(e){return null!==e.match(/[,!%&@#$^*?_~]/)}};e(this).on("input focus",function(){for(var s in l(),r){var t=p[s](e(this).val()),n=t?"addClass":"removeClass";r[s]=t,e(".pr-"+s.slice(0,-4)+" span")[n]("pr-ok")}})}})},e.fn.passwordRequirements.getPos=function(s){var t=e(s).offset().top,n=e(s).innerHeight(),a=t+n,r=e(s).offset().left;return{top:a,left:r}},e.fn.passwordRequirements.defaults={numCharacters:8,useLowercase:!0,useUppercase:!0,useNumbers:!0,useSpecial:!0,infoMessage:"",style:"light",fadeTime:300},e.fn.passwordRequirements.locales=[],e.fn.passwordRequirements.locales.en={infoMessageText:"The minimum password length is {0} characters and must contain at least 1 lowercase letter, 1 capital letter, 1 number, and 1 special character.",numCharactersText:"# of characters",useLowercaseText:"Lowercase letter",useUppercaseText:"Capital letter",useNumbersText:"Number",useSpecialText:"Special character"},e.extend(e.fn.passwordRequirements.defaults,e.fn.passwordRequirements.locales.en),e(window).resize(function(){e(".pr-box").get(0).updatePos()})})(jQuery); \ No newline at end of file From 2ed154edcad482721c65bcc60a7571644a381e8e Mon Sep 17 00:00:00 2001 From: Misteregis Date: Thu, 20 Oct 2022 00:21:30 -0300 Subject: [PATCH 2/2] Added locale (pt_BR) --- demo.html | 21 +++--- js/jquery.passwordRequirements.js | 104 +++++++++++++++++++++----- js/jquery.passwordRequirements.min.js | 13 +++- locale/pt_BR.js | 26 +++++++ 4 files changed, 136 insertions(+), 28 deletions(-) create mode 100644 locale/pt_BR.js diff --git a/demo.html b/demo.html index e3cc48a..df3e4dd 100644 --- a/demo.html +++ b/demo.html @@ -2,24 +2,25 @@ - - - - + + + +
        - - - + + + - + + \ No newline at end of file diff --git a/js/jquery.passwordRequirements.js b/js/jquery.passwordRequirements.js index 14ef8b6..4d93d1c 100644 --- a/js/jquery.passwordRequirements.js +++ b/js/jquery.passwordRequirements.js @@ -7,21 +7,53 @@ * http://www.opensource.org/licenses/mit-license.php * * Modified by: Misteregis - * Modified date: 2022/10/18 + * Modified date: 2022/10/20 */ - (function ($) { $.fn.passwordRequirements = function (options) { // options for the plugin options = $.extend($.fn.passwordRequirements.defaults, options); return this.each(function () { - var o = options; var $this = this; + var info = o.infoMessageTextArray; + var infoMessage = ''; + var infoToUse = {}; + + infoMessage = info.minCharacters.replace('{0}', o.minCharacters || o.numCharacters); + + if (o.maxCharacters) { + infoMessage += ' ' + info.maxCharacters.replace('{0}', o.maxCharacters); + } + + for (var opt in o) { + if (['minCharacters', 'maxCharacters'].includes(opt)) continue; + + if (info.hasOwnProperty(opt) && o[opt] && !infoToUse.hasOwnProperty(opt)) { + infoToUse[opt] = info[opt].replace('{0}', o[opt]); + } + } + + infoToUse = Object.values(infoToUse); + + if (infoToUse.length) { + var last = infoToUse[0]; + var at_least = last; + + if (infoToUse.length > 1) { + last = infoToUse.pop(); + + at_least = infoToUse.join(', ') + info.and + last; + } + + infoMessage += ' ' + info.mustContain + ' ' + at_least; + } + + infoMessage += '.'; - o.infoMessage = o.infoMessageText.replace('{0}', o.numCharacters); + this.passwordRequirements = { infoMessage }; var lis = [], toCheck = {}; @@ -51,7 +83,7 @@ if (!$("#" + id).length) { var em = $(''); var ul = $('
          ').append(lis); - var p = $('

          ', { text: o.infoMessage }); + var p = $('

          ', { text: $this.passwordRequirements.infoMessage }); var prBoxInner = $('

          ', { class: 'pr-box-inner' }).append([p, ul]); var prBox = $('
          ', { id, class: 'pr-box' }).append([em, prBoxInner]); @@ -98,32 +130,58 @@ } else { showMessage(); } + checked(); }; // Show password hint $(this).on("blur", deleteMessage); + var range = { + min: o.minCharacters || o.numCharacters, + max: o.maxCharacters || '' + }; // Show or Hide password hint based on user's event // Set variables var regex = { - numCharactersDone: function (val) { return val.length >= o.numCharacters }, - useLowercaseDone: function (val) { return val.match(/[a-z]/) !== null }, - useUppercaseDone: function (val) { return val.match(/[A-Z]/) !== null }, - useNumbersDone: function (val) { return val.match(/\d/) !== null }, - useSpecialDone: function (val) { return val.match(/[,!%&@#$^*?_~]/) !== null } + useSpecial: /[,!%&@#$^*?_~=]/, + useNumbers: /\d/, + useLowercase: /[a-z]/, + useUppercase: /[A-Z]/, + numCharacters: eval('/^(?=.{' + range.min + ',' + range.max + '}$).+/'), }; - // Show or Hide password hint based on keyup (input) - $(this).on("input focus", function () { - checkCompleted(); + // The pattern string + var pattern = ''; + + // Build the pattern string + for (var key in regex) { + if (o[key]) { + var rgx = regex[key].source; + pattern += rgx.includes('(') ? rgx : '(?=.*' + rgx + ')'; + } + } + + if (pattern) { + // Apply pattern to input + $(this).attr({ + maxlength: o.maxCharacters, + minlength: range.min, + pattern + }); + } + + // Show or Hide password hint based on keyup (input) and apply pattern + $(this).on("input focus", function (e) { for (var key in toCheck) { - var done = regex[key]($(this).val()); + var done = $(this).val().match(regex[key.slice(0, -4)]) !== null; var cls = done ? 'addClass' : 'removeClass'; toCheck[key] = done; + checkCompleted(); + $(".pr-" + key.slice(0, -4) + " span")[cls]("pr-ok"); } }); @@ -142,11 +200,12 @@ // plugin defaults $.fn.passwordRequirements.defaults = { numCharacters: 8, + minCharacters: null, + maxCharacters: null, useLowercase: true, useUppercase: true, useNumbers: true, useSpecial: true, - infoMessage: '', style: "light", // Style Options light or dark fadeTime: 300 // FadeIn / FadeOut in milliseconds }; @@ -154,7 +213,16 @@ $.fn.passwordRequirements.locales = []; $.fn.passwordRequirements.locales["en"] = { - infoMessageText: "The minimum password length is {0} characters and must contain at least 1 lowercase letter, 1 capital letter, 1 number, and 1 special character.", + infoMessageTextArray: { + minCharacters: "The minimum password length is {0} characters", + maxCharacters: "and the maximum is {0} characters", + mustContain: "and must contain at least", + useLowercase: "1 lowercase letter", + useUppercase: "1 capital letter", + useNumbers: "1 number", + useSpecial: "1 special character", + and: " and " + }, numCharactersText: "# of characters", useLowercaseText: "Lowercase letter", useUppercaseText: "Capital letter", @@ -165,6 +233,8 @@ $.extend($.fn.passwordRequirements.defaults, $.fn.passwordRequirements.locales['en']); $(window).resize(function () { - $(".pr-box").get(0).updatePos(); + if ($(".pr-box").length) { + $(".pr-box").get(0).updatePos(); + } }); })(jQuery); diff --git a/js/jquery.passwordRequirements.min.js b/js/jquery.passwordRequirements.min.js index b80bf76..c54167f 100644 --- a/js/jquery.passwordRequirements.min.js +++ b/js/jquery.passwordRequirements.min.js @@ -1 +1,12 @@ -(function(e){e.fn.passwordRequirements=function(s){return s=e.extend(e.fn.passwordRequirements.defaults,s),this.each(function(){var t=s,n=this;t.infoMessage=t.infoMessageText.replace("{0}",t.numCharacters);var a=[],r={};if(e(["numCharacters","useLowercase","useUppercase","useNumbers","useSpecial"]).each(function(s,n){t[n]&&(a.push(e("
        • ",{class:"pr-"+n,html:""+t[n+"Text"]})),r[n+"Done"]=!1)}),a.length){var o=Object.keys(r).length,u=function(){return Object.values(r).filter(e=>!0===e).length===o},i=function(){u()||e(".pr-password").each(function(){var s="pr-box-"+e(".pr-password").index(n);if(!e("#"+s).length){var r=e(""),o=e("
            ").append(a),u=e("

            ",{text:t.infoMessage}),i=e("

            ",{class:"pr-box-inner"}).append([u,o]),c=e("
            ",{id:s,class:"pr-box"}).append([r,i]);c.get(0)._element=n,c.get(0).updatePos=function(){var s=e(this._element).offset().top,t=e(this._element).innerHeight(),n=s+t,a=e(this._element).offset().left;e(this).css({top:n,left:a})},e(".pr-box").remove(),e("body").append(c),c.addClass(t.style).fadeIn(t.fadeTime).get(0).updatePos(),scroll({top:n.offsetTop,behavior:"smooth"})}})};e(this).on("focus",i);var c=function(){e(".pr-box").fadeOut(t.fadeTime,function(){e(this).remove()})},l=function(){u()?c():i()};e(this).on("blur",c);var p={numCharactersDone:function(e){return e.length>=t.numCharacters},useLowercaseDone:function(e){return null!==e.match(/[a-z]/)},useUppercaseDone:function(e){return null!==e.match(/[A-Z]/)},useNumbersDone:function(e){return null!==e.match(/\d/)},useSpecialDone:function(e){return null!==e.match(/[,!%&@#$^*?_~]/)}};e(this).on("input focus",function(){for(var s in l(),r){var t=p[s](e(this).val()),n=t?"addClass":"removeClass";r[s]=t,e(".pr-"+s.slice(0,-4)+" span")[n]("pr-ok")}})}})},e.fn.passwordRequirements.getPos=function(s){var t=e(s).offset().top,n=e(s).innerHeight(),a=t+n,r=e(s).offset().left;return{top:a,left:r}},e.fn.passwordRequirements.defaults={numCharacters:8,useLowercase:!0,useUppercase:!0,useNumbers:!0,useSpecial:!0,infoMessage:"",style:"light",fadeTime:300},e.fn.passwordRequirements.locales=[],e.fn.passwordRequirements.locales.en={infoMessageText:"The minimum password length is {0} characters and must contain at least 1 lowercase letter, 1 capital letter, 1 number, and 1 special character.",numCharactersText:"# of characters",useLowercaseText:"Lowercase letter",useUppercaseText:"Capital letter",useNumbersText:"Number",useSpecialText:"Special character"},e.extend(e.fn.passwordRequirements.defaults,e.fn.passwordRequirements.locales.en),e(window).resize(function(){e(".pr-box").get(0).updatePos()})})(jQuery); \ No newline at end of file +/* + * jQuery Minimun Password Requirements 1.2 + * http://elationbase.com + * Copyright 2014, elationbase + * Check Minimun Password Requirements + * Free to use under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Modified by: Misteregis + * Modified date: 2022/10/20 +*/ +(function($){$.fn.passwordRequirements=function(options){return options=$.extend($.fn.passwordRequirements.defaults,options),this.each(function(){var o=options,$this=this,info=o.infoMessageTextArray,infoMessage="",infoToUse={};for(var opt in infoMessage=info.minCharacters.replace("{0}",o.minCharacters||o.numCharacters),o.maxCharacters&&(infoMessage+=" "+info.maxCharacters.replace("{0}",o.maxCharacters)),o)["minCharacters","maxCharacters"].includes(opt)||info.hasOwnProperty(opt)&&o[opt]&&!infoToUse.hasOwnProperty(opt)&&(infoToUse[opt]=info[opt].replace("{0}",o[opt]));if(infoToUse=Object.values(infoToUse),infoToUse.length){var last=infoToUse[0],at_least=last;infoToUse.length>1&&(last=infoToUse.pop(),at_least=infoToUse.join(", ")+info.and+last),infoMessage+=" "+info.mustContain+" "+at_least}infoMessage+=".",this.passwordRequirements={infoMessage:infoMessage};var lis=[],toCheck={};if($(["numCharacters","useLowercase","useUppercase","useNumbers","useSpecial"]).each(function(e,s){o[s]&&(lis.push($("
          • ",{class:"pr-"+s,html:""+o[s+"Text"]})),toCheck[s+"Done"]=!1)}),lis.length){var toCheckTotal=Object.keys(toCheck).length,checked=function(){return Object.values(toCheck).filter(e=>!0===e).length===toCheckTotal},showMessage=function(){checked()||$(".pr-password").each(function(){var e="pr-box-"+$(".pr-password").index($this);if(!$("#"+e).length){var s=$(""),a=$("
              ").append(lis),t=$("

              ",{text:$this.passwordRequirements.infoMessage}),r=$("

              ",{class:"pr-box-inner"}).append([t,a]),n=$("
              ",{id:e,class:"pr-box"}).append([s,r]);n.get(0)._element=$this,n.get(0).updatePos=function(){var e=$(this._element).offset().top,s=$(this._element).innerHeight(),a=e+s,t=$(this._element).offset().left;$(this).css({top:a,left:t})},$(".pr-box").remove(),$("body").append(n),n.addClass(o.style).fadeIn(o.fadeTime).get(0).updatePos(),scroll({top:$this.offsetTop,behavior:"smooth"})}})};$(this).on("focus",showMessage);var deleteMessage=function(){$(".pr-box").fadeOut(o.fadeTime,function(){$(this).remove()})},checkCompleted=function(){checked()?deleteMessage():showMessage(),checked()};$(this).on("blur",deleteMessage);var range={min:o.minCharacters||o.numCharacters,max:o.maxCharacters||""},regex={useSpecial:/[,!%&@#$^*?_~=]/,useNumbers:/\d/,useLowercase:/[a-z]/,useUppercase:/[A-Z]/,numCharacters:eval("/^(?=.{"+range.min+","+range.max+"}$).+/")},pattern="";for(var key in regex)if(o[key]){var rgx=regex[key].source;pattern+=rgx.includes("(")?rgx:"(?=.*"+rgx+")"}pattern&&$(this).attr({maxlength:o.maxCharacters,minlength:range.min,pattern:pattern}),$(this).on("input focus",function(e){for(var s in toCheck){var a=null!==$(this).val().match(regex[s.slice(0,-4)]),t=a?"addClass":"removeClass";toCheck[s]=a,checkCompleted(),$(".pr-"+s.slice(0,-4)+" span")[t]("pr-ok")}})}})},$.fn.passwordRequirements.getPos=function(e){var s=$(e).offset().top,a=$(e).innerHeight(),t=s+a,o=$(e).offset().left;return{top:t,left:o}},$.fn.passwordRequirements.defaults={numCharacters:8,minCharacters:null,maxCharacters:null,useLowercase:!0,useUppercase:!0,useNumbers:!0,useSpecial:!0,style:"light",fadeTime:300},$.fn.passwordRequirements.locales=[],$.fn.passwordRequirements.locales.en={infoMessageTextArray:{minCharacters:"The minimum password length is {0} characters",maxCharacters:"and the maximum is {0} characters",mustContain:"and must contain at least",useLowercase:"1 lowercase letter",useUppercase:"1 capital letter",useNumbers:"1 number",useSpecial:"1 special character",and:" and "},numCharactersText:"# of characters",useLowercaseText:"Lowercase letter",useUppercaseText:"Capital letter",useNumbersText:"Number",useSpecialText:"Special character"},$.extend($.fn.passwordRequirements.defaults,$.fn.passwordRequirements.locales.en),$(window).resize(function(){$(".pr-box").length&&$(".pr-box").get(0).updatePos()})})(jQuery); \ No newline at end of file diff --git a/locale/pt_BR.js b/locale/pt_BR.js new file mode 100644 index 0000000..019dcfc --- /dev/null +++ b/locale/pt_BR.js @@ -0,0 +1,26 @@ +/** + * jQuery Minimun Password Requirements Brazilian Portuguese translation + */ +(function ($) { + "use strict"; + + $.fn.passwordRequirements.locales['pt-BR'] = { + infoMessageTextArray: { + minCharacters: "A senha deve ter no mínimo {0} caracteres", + maxCharacters: "e no máximo {0}", + mustContain: "e ela também deve conter ao menos", + useLowercase: "1 letra minúscula", + useUppercase: "1 letra maiúscula", + useNumbers: "1 número", + useSpecial: "1 caractere especial", + and: " e " + }, + numCharactersText: "# de caracteres", + useLowercaseText: "Letra minúscula", + useUppercaseText: "Letra maiúscula", + useNumbersText: "Número", + useSpecialText: "Caractere especial" + }; + + $.extend($.fn.passwordRequirements.defaults, $.fn.passwordRequirements.locales['pt-BR']); +})(jQuery); \ No newline at end of file