Валидация пароля на JavaScript

Рассмотрим случай, когда валидация пароля и показ ошибок происходит до отправки и проверки на сервер.

Как выводить ошибку ввода пароля?

Начинаем уже по традиции с написания HTML:

<div class="personal-form-wrap">
<div class="password-title">Для зміни пароля, придумайте і введіть новий пароль</div>
<div id="errors" class="error"><pre></pre></div>
<form class="profile__form" method="POST" enctype="multipart/form-data">
<input type="hidden" name="profile" value="update">

<div class="profile__form-row">
<div class="form-input-item">
<input id="myPassword" type="password" placeholder="Пароль" class="form-input jqPassField" name="password" value="" style="border: 2px solid green;">
</div>
<div class="form-input-item">
<input id="myConfirmPassword" type="password" placeholder="Подтвердить пароль" class="form-input jqPassConfirmField" name="confirm" value="" style="border: 2px solid green;">
</div>
</div>
<button class="btn-submit" type="submit">Зберегти</button>
<div class="password-desc">Пароль должен состоять минимум из 8 символов, 1 заглавной буквы, 1 спец символа, 1 цифры</div>
</form>
</div>

Дальше будет большая простыня из JavaScript`а, но вы не пугайтесь, я сейчас всё объясню 🙂 .

(function($) {
	$.fn.extend({
		passwordValidation: function(_options, _callback, _confirmcallback) {
			//var _unicodeSpecialSet = "^\\x00-\\x1F\\x7F\\x80-\\x9F0-9A-Za-z"; //All chars other than above (and C0/C1)
			var CHARSETS = {
				upperCaseSet: "A-Z", 	//All UpperCase (Acii/Unicode)
				lowerCaseSet: "a-z", 	//All LowerCase (Acii/Unicode)
				digitSet: "0-9", 		//All digits (Acii/Unicode)
				specialSet: "\\x20-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E\\x80-\\xFF", //All Other printable Ascii
			}
			var _defaults = {
				minLength: 8,		  //Minimum Length of password 
				minUpperCase: 1,	  //Minimum number of Upper Case Letters characters in password
				minLowerCase: 2,	  //Minimum number of Lower Case Letters characters in password
				minDigits: 1,		  //Minimum number of digits characters in password
				minSpecial: 1,		  //Minimum number of special characters in password
				maxRepeats: 5,		  //Maximum number of repeated alphanumeric characters in password dhgurAAAfjewd <- 3 A's
				maxConsecutive: 3,	  //Maximum number of alphanumeric characters from one set back to back
				noUpper: false,		  //Disallow Upper Case Lettera
				noLower: false,		  //Disallow Lower Case Letters
				noDigit: false,		  //Disallow Digits
				noSpecial: false,	  //Disallow Special Characters
				//NOT IMPLEMENTED YET allowUnicode: false,  //Switches Ascii Special Set out for Unicode Special Set 
				failRepeats: true,    //Disallow user to have x number of repeated alphanumeric characters ex.. ..A..a..A.. <- fails if maxRepeats <= 3 CASE INSENSITIVE
				failConsecutive: true,//Disallow user to have x number of consecutive alphanumeric characters from any set ex.. abc <- fails if maxConsecutive <= 3
				confirmField: undefined
			};

			//Ensure parameters are correctly defined
			if($.isFunction(_options)) {
				if($.isFunction(_callback)) {
					if($.isFunction(_confirmcallback)) {
						console.log("Предупреждение в passValidate: было определено 3 или более обратных вызова ... Будут использоваться первые два.");
					}
					_confirmcallback = _callback;
				}
				_callback = _options;
				_options = {};
			}

			//concatenate user options with _defaults
			_options = $.extend(_defaults, _options);
			if(_options.maxRepeats < 2) _options.maxRepeats = 2; function charsetToString() { return CHARSETS.upperCaseSet + CHARSETS.lowerCaseSet + CHARSETS.digitSet + CHARSETS.specialSet; } //GENERATE ALL REGEXs FOR EVERY CASE function buildPasswordRegex() { var cases = []; //if(_options.allowUnicode) CHARSETS.specialSet = _unicodeSpecialSet; if (_options.noUpper) { cases.push({"regex": "(?=" + CHARSETS.upperCaseSet + ")", "message": "Пароль не может содержать заглавные буквы"}); } else { cases.push({"regex": "(?=" + ("[" + CHARSETS.upperCaseSet + "][^" + CHARSETS.upperCaseSet + "]*").repeat(_options.minUpperCase) + ")", "message": "Пароль должен содержать не менее " + _options.minUpperCase + " Заглавной буквы."}); } if (_options.noLower) { cases.push({"regex": "(?=" + CHARSETS.lowerCaseSet + ")", "message": "Пароль не может содержать строчные буквы"}); } else { cases.push({"regex": "(?=" + ("[" + CHARSETS.lowerCaseSet + "][^" + CHARSETS.lowerCaseSet + "]*").repeat(_options.minLowerCase) + ")", "message": "Пароль должен содержать не менее " + _options.minLowerCase + " Строчных букв."}); } if (_options.noDigit) { cases.push({"regex": "(?=" + CHARSETS.digitSet + ")", "message": "Пароль не может содержать число"}); } else { cases.push({"regex": "(?=" + ("[" + CHARSETS.digitSet + "][^" + CHARSETS.digitSet + "]*").repeat(_options.minDigits) + ")", "message": "Пароль должен содержать не менее " + _options.minDigits + " Цифры."}); } if (_options.noSpecial) { cases.push({"regex": "(?=" + CHARSETS.specialSet + ")", "message": "Пароль не может содержать специальный символ"}); } else { cases.push({"regex": "(?=" + ("[" + CHARSETS.specialSet + "][^" + CHARSETS.specialSet + "]*").repeat(_options.minSpecial) + ")", "message": "Пароль должен содержать не менее " + _options.minSpecial + " Специального символа."}); } cases.push({"regex":"[" + charsetToString() + "]{" + _options.minLength + ",}", "message":"Пароль должен содержать не менее " + _options.minLength + " символов."}); return cases; } var _cases = buildPasswordRegex(); var _element = this; var $confirmField = (_options.confirmField != undefined)? $(_options.confirmField): undefined; //Field validation on every captured event function validateField() { var failedCases = []; //Evaluate all verbose cases $.each(_cases, function(i, _case) { if($(_element).val().search(new RegExp(_case.regex, "g")) == -1) { failedCases.push(_case.message); } }); if(_options.failRepeats && $(_element).val().search(new RegExp("(.)" + (".*\\1").repeat(_options.maxRepeats - 1), "gi")) != -1) { failedCases.push("Пароль не может содержать " + _options.maxRepeats + " одного и того же символа без учета регистра."); } if(_options.failConsecutive && $(_element).val().search(new RegExp("(?=(.)" + ("\\1").repeat(_options.maxConsecutive) + ")", "g")) != -1) { failedCases.push("Пароль не может содержать один и тот же символ более чем " + _options.maxConsecutive + " раз подряд."); } //Determine if valid var validPassword = (failedCases.length == 0) && ($(_element).val().length >= _options.minLength);
				var fieldsMatch = true;
				if($confirmField != undefined) {
					fieldsMatch = ($confirmField.val() == $(_element).val());
				}

				_callback(_element, validPassword, validPassword && fieldsMatch, failedCases);
			}

			//Add custom classes to fields
			this.each(function() {
				//Validate field if it is already filled
				if($(this).val()) {
					validateField().apply(this);
				}

				$(this).toggleClass("jqPassField", true);
				if($confirmField != undefined) {
					$confirmField.toggleClass("jqPassConfirmField", true);
				}
			});

			//Add event bindings to the password fields
			return this.each(function() {
				$(this).bind('keyup focus input proprtychange mouseup', validateField);
				if($confirmField != undefined) {
					$confirmField.bind('keyup focus input proprtychange mouseup', validateField);
				}
			});
		}
	});
})(jQuery);


$(function(){
	$("#myPassword").passwordValidation({"confirmField": "#myConfirmPassword"}, function(element, valid, match, failedCases) {
		$("#errors").html("
" + failedCases.join("\n") + "
"); if(valid) $(element).css("border","2px solid green"); if(!valid) $(element).css("border","2px solid red"); if(valid && match) { $("#myConfirmPassword").css("border","2px solid green"); $('.btn-submit').removeClass('disable'); } if(!valid || !match) { $("#myConfirmPassword").css("border","2px solid red"); $('.btn-submit').addClass('disable'); } }); });

По HTML думаю вопросов не должно возникнуть, но обратите внимание на id, т.к. именно к ним мы и будем привязываться.

Что касается JS:
var CHARSETS – перечень регулярных выражений
var _defaults – наши настройки по умолчанию, которые мы можем менять как нам вздумается. Именно тут и просиходит вся магия. Овладев базовыми знаниями английского языка (или воспользовавшись переводчиком 🙂 ) можно без труда понять какой параметр и что означает.

Что еще интересного в этом скрипте? Ну например, в самом его конце можно увидеть добавление класса disable. Дописав pointer-events в CSS можно отключить нажатие кнопки. На каждое несоответствие регулярному выражению – выводится своя ошибка, но немного помозговав можно переписать под одну общую фразу.

автор: Dmitriy

З 2011 року займаюся веб-розробкою. Зараз я – PHP Full Stack Developer.
Обговорити ваш проект, а також дізнатися більше про мене ви можете на цьому сайті:
dev.forwww.com

Email: dmitriyribka@gmail.com

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *