Виды валидации
Существует три вида валидаций: мгновенная, по потере фокуса и по отправке формы.
Чем раньше интерфейс сообщает об ошибке, тем лучше — пользователю проще вернуться и исправить ошибку.
Самый быстрый способ сообщить об ошибке — мгновенная валидация. Но она возможна только в тех случаях, когда в процессе ввода понятно, что значение некорректное. Обычно такие ошибки связаны с неправильной раскладкой клавиатуры (кириллица вместо латиницы) или вводом букв в цифровое поле (ИНН, КПП и др.) Для этих случаев мы используем поля с масками: ввод неподходящих символов в них заблокирован. Поэтому в наших интерфейсах есть только два вида валидации:
- по потере фокуса — основной вид валидации
- по отправке формы — для тех случаев, когда валидация по потере фокуса невозможна.
Используем JavaScript
JavaScript даёт намного больше возможностей для улучшения работы пользователей с формами. Давайте рассмотрим в качестве примера три числовых поля, у каждого из которых установлен минимум в 10, максимум в 100 и шаг в 10 единиц.
Устанавливая атрибуты , и , мы можем быть уверены в правильности значения только тогда, когда пользователь использует специальные контролы числового поля. Но что мешает пользователю ввести вручную некорректные данные? Вот что произойдёт, если он вставит , и в три поля и отправит форму:
Стандартный тултип валидации
В результате всё, что получит пользователь — это сообщение об ошибке для первого поля. Кроме того, в этом сообщении будет указано лишь одно несоответствие из двух требуемых. Такое поведение можно исправить, изменяя показываемые валидатором сообщения.
Добавляем несколько сообщений об ошибках в один тултип
Валидируя поля, браузер проверяет их по определённому списку потенциальных ошибок. В каждом поле содержится специальный объект , включающий в себя список булевых значений, характеризующих ту или иную проверку на валидность. Например, вот такой -объект будет у поля, когда пользователь введёт в него :
Примечание переводчика: Слово «mismatch» переводится как «несоответствие». Поэтому в значениях , и обратная логика: — значение не удовлетворяет атрибуту, — удовлетворяет.
По умолчанию браузер отобразит лишь одну ошибку. Что мы можем сделать, так это проверить все эти значения самостоятельно и, если найдутся ошибки, сохранить их. Как только мы сохраним все ошибки для одного поля, мы можем отобразить весь их список в виде специального сообщения об ошибке при помощи функции .
Теперь при попытке отправить форму мы увидим вот это:
Отображаем несколько ошибок в одном тултипе
Стало лучше, поскольку теперь будут показываться все сообщения об ошибках, связанные с конкретным полем. Однако другая проблема всё ещё не решена: ошибки по-прежнему показываются лишь для первого поля.
Это ограничение валидации, устанавливаемое браузером. Чтобы его побороть, нам нужно пойти другим путём.
Показываем все ошибки для всех полей.
Вместо того, чтобы использовать встроенный тултип, мы можем добавлять сообщения об ошибках напрямую в DOM. Таким образом, все ошибки будут выводиться рядом с соответствующим полем.
Этого можно добиться какой-то парой дополнительных строчек в нашем коде:
Вот что происходит при клике на submit теперь:
Отображаем все ошибки для всех полей в DOM
Используем нестандартные проверки валидности
Иногда встроенной в браузер валидации бывает недостаточно. Нам может понадобиться, чтобы вводимые данные удовлетворяли некоторым дополнительным правилам. Например, чтобы в текстовом поле требовалось указать особые символы.
Так как мы уже проверяем все возможные ошибки вручную в нашей функции , мы можем просто-напросто добавить туда ещё несколько проверок.
Валидация в реальном времени
Хотя текущий способ выглядит намного лучше, он тоже не без изъянов. Наихудший из недочётов заключается в том, что пользователь не сможет увидеть никаких сообщений, пока не нажмёт на кнопку отправки формы. Было бы гораздо лучше, если бы валидация поля происходила сразу же при его заполнении. Можно выделить три правила для того, чтобы с формой было удобно работать:
- Требования для каждого поля чётко видны до того, как пользователь начал печатать.
- Как только пользователь начинает вводить данные, соблюдая требования, он сразу видит индикатор успешного заполнения поля или подсказки, если есть ошибки.
- Нужно отображать сообщения об ошибках таким образом, чтобы пользователь не мог отправить некорректно заполненную форму.
Пример валидации в реальном времени
Если вы хотите попробовать свои силы (и даже сделать получше), вы можете воспользоваться вот этим шаблоном.
Дополнительные опции настройки плагина
Вы можете отключить валидацию при случайном переходе в поле с помощью клавиши или при клике мышью. Для этого надо установить параметры onfocusout, onkeyup, или onclick на false
Обратите внимание, что логическое true не является допустимым значением для этих событий. Другими словами, если вы хотите, чтобы плагин осуществлял валидацию при этих событиях – просто оставьте соответствующие ключи без изменений
У вас также есть возможность изменить элемент, который используется для вывода ошибок. По умолчанию используется label, но при желании вы можете изменить его на em или любой другой элемент, используя параметр errorElemet. Выбранный элемент, в свою очередь, можно обернуть в другой HTML-элемент, применив параметр wrapper.
Рассмотренные варианты – наиболее типичные опции валидации данных. Кроме этих вариантов, вам могут пригодиться и некоторые другие – например, если вы захотите изменить местоположение уведомлений или сгруппировать их вместе.
Добавление правил валидации для полей ввода
Вы также можете передать определенные правила в метод validate() для установления правил, в соответствии с которыми должна проверяться введенная информация. Значением параметра rules должны быть пары «ключ-значение». Ключом в каждом случае является название проверяемого элемента, а значением – набор правил для проверки информации.
Также можно добавить проверку условий данных в различных полях – с использованием ключевого слова depends («зависит от») и возвращая, соответственно, результат true («истинно») или false («ложно»). Ниже приведен пример использования простого набора правил для определения корректности введенных данных:
$(document).ready(function() { $("#basic-form").validate({ rules: { name : { required: true, minlength: 3 }, age: { required: true, number: true, min: 18 }, email: { required: true, email: true }, weight: { required: { depends: function(elem) { return $("#age").val() > 50 } }, number: true, min: 0 } } }); });
Примеры валидации форм с помощью JQuery
Такие опции валидации схожи с атрибутами, которые вы можете добавить в разметку формы. Например, установка параметра required на true сделает элемент обязательно необходимым для успешной отправки формы. Установление minlength на значение 3 обяжет пользователей вводить в поле как минимум три символа. Есть и другие встроенные методы валидации, с которыми можно ознакомиться на странице с технической документацией.
Важный момент, на который необходимо обратить внимание в приведенном выше коде – использование depends для того, чтобы сделать обязательным условием ввод веса, если возраст превышает 50 лет. Условие реализовано с помощью возвращения значения true функцией обратного вызова в том случае, если значение, введенное в поле age, превышает 50
Валидация на стороне клиента
Последнее обновление: 08.12.2019
Валидация на стороне клиента позволяет уменьшить количество обращений к серверу и произвести все действия по проверке значений непосредственно при вводе данных.
Для определения валидации на стороне клиента необходимо подключить в представлении специальные скрипты валидации:
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"></script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js"></script>
Актуальная версия скриптов в будущем может отличаться. Но по умолчанию эти же скрипты по умолчанию уже есть в проекте в папке wwwroot/lib,
и мы можем совместить подключение из CDN и подключение из проекта (в случае есть из CDN не удастся подключиться):
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js" asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js" asp-fallback-test="window.jQuery && window.jQuery.validator"> </script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js" asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"> </script>
Единственное, что надо учитывать, что эти скрипты зависят от основной библиотеки jquery, поэтому перед подключением скриптов валидации должно идти подключение jquery.
Кроме того, в проекте по типу Web Application (Model-View-Controller) по умолчанию в папке Views/Shared добавляется
файл частичного представления _ValidationScriptsPartial, который опять же содержит подключения выше упомянутых скриптов:
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
Поэтому в принципе мы можем подключать скрипты через данное частичное представление.
Для валидации и отображения ошибок фреймворк MVC использует атрибуты валидации в дополнение к метаданным свойств модели. Когда MVC производит рендеринг
элементов формы с помощью tag-хелперов или html-хелперов, к элементам формы добавляются data-атрибуты HTML 5.
Например, пусть в модели определено свойство Name:
public string Name { get; set; }
Тогда следующее определение поля ввода с помощью tag-хелперов:
<label asp-for="Name"></label><br /> <input type="text" asp-for="Name" /> <span asp-validation-for="Name"></span>
сгенерирует следующую разметку:
<label for="Name">Name</label><br /> <input type="text" data-val="true" data-val-required="Не указано имя" id="Name" name="Name" value="" /> <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
Стилизация сообщений об ошибках
Когда происходит валидация, то при отображении ошибок соответствующим полям присваиваются определенные классы css. Используя эти классы, мы можем настроить
отображение сообщений. Например, добавим в представление или в подключаемый файл css следующие стили:
.field-validation-error { color: #b94a48; } .field-validation-valid { display: none; } input.input-validation-error { border: 1px solid #b94a48; } input.input-validation-error { border: 0 none; } .validation-summary-errors { color: #b94a48; } .validation-summary-valid { display: none; }
Класс добавляется для сводки ошибок всей модели над формой. Класс добавляется
к элементам , которые отображают текст ошибки. И класс добавляется для полей ввода, которые содержат
некорректные данные. Управляя этими классами, мы можем должным образом стилизовать элементы формы.
НазадВперед
Final Thoughts
In this tutorial, we learned how to take our form validation to the next level using a jQuery plugin. Using simple JavaScript form validation gives us a lot of additional control over basic HTML validation. For instance, you can easily control how and when different error messages appear when an input is filled with invalid values.
Similarly, you can also specify if the plugin should skip validation for some particular elements. I’d strongly recommend that you read the documentation of this plugin and some best practices on how to use it properly.
In our next tutorial, you’ll learn about some more JavaScript-based tools and plugins to help you easily create and validate forms.
And while you’re here, check out some of our other posts on JavaScript forms and form validation!
CSS-селекторы, используемые для оформления
Чекбокс | |
---|---|
чекбокс по умолчанию | |
дополнительный вложенный тег | |
выбранный чекбокс | |
неактивный (недоступный для выбора) чекбокс | |
фокус на чекбоксе, когда нажата клавиша Tab | |
дополнительный вложенный тег | |
Радиокнопка | |
радиокнопка по умолчанию | |
дополнительный вложенный тег | |
выбранная радиокнопка | |
неактивная (недоступная для выбора) радиокнопка | |
фокус на радиокнопке, когда нажата клавиша Tab | |
дополнительный вложенный тег | |
Поле для выбора файла | |
родительский контейнер | |
фокус на поле | |
файл выбран | |
неактивное поле | |
поле с именем файла | |
кнопка выбора файла | |
Поле для ввода чисел | |
родительский контейнер | |
фокус на поле | |
неактивное поле | |
обертка для поля ввода | |
кнопка «минус» | |
кнопка «плюс» | |
Селект (простой) | |
родительский контейнер | |
выпадающий список селекта раскрыт | |
выпадающий список селекта раскрыт вверх | |
выпадающий список селекта раскрыт вниз | |
выбрано значение, отличное от заданного по умолчанию | |
селект в свернутом состоянии | |
фокус на селекте, когда нажата клавиша Tab | |
неактивный (недоступный для выбора) селект | |
дополнительный вложенный тег для свернутого селекта | |
замещающий текст | |
правая часть свернутого селекта (условный переключатель) | |
вложенный тег для переключателя (стрелка) | |
обертка для выпадающего списка | |
обертка для поискового поля | |
поисковое поле | |
сообщение об отсутствии результатов поиска | |
выпадающий список | |
пункт (опция) селекта | |
выбранный пункт селекта | |
неактивный (недоступный для выбора) пункт селекта | |
заголовок для группы пунктов | |
пункт списка в группе | |
Селект (множественный) | |
родительский контейнер | |
неактивный (недоступный для выбора) селект | |
пункт (опция) селекта | |
выбранный пункт селекта | |
неактивный (недоступный для выбора) пункт селекта | |
заголовок для группы пунктов | |
пункт списка в группе | |
Прочие элементы (только CSS) | |
класс, используемый для стилизации текстовых полей и кнопок (работает независимо от плагина) |
Использование встроенной валидации форм
Одной из самых важных функций элементов форм HTML5 является способность валидировать бóльшую часть пользовательских данных без использования JavaScript. Это выполняется с помощью атрибутов валидации у элементов формы. Многие из них мы уже рассмотрели в этом курсе:
- : Определяет, что для отправки формы данное поле предварительно должно быть заполнено.
- и : Задаёт минимальную и максимальную длину текстовых данных (строк)
- и : Задаёт минимальное и максимальное значение для поля, расчитанного на числовой тип данных
- : Определяет тип данных, на который рассчитано поле: число, email-адрес или какой-то другой предустановленный тип
- : С помощью регулярного выражения, определяет шаблон, которому должны соответствовать вводимые данные.
Если данные, введённые в поле формы, соответствуют правилам перечисленных выше атрибутов, они считаются валидными, если нет — не валидными
Когда элемент валиден, справедливы следующие утверждения:
- Элемент соответствует CSS-псевдоклассу , позволяющему стилизовать только валидные элементы.
- Если пользователь пытается отправить данные, браузер отправит форму при условии, что ничто другое (например, JavaScript) не помешает ему это сделать
Когда элемент не валиден, справедливы следующие утверждения:
- Элемент соответствует CSS-псевдоклассу или, в зависимости от ошибки, другим псевдоклассам (например, ), которые позволяют применять определённые стили к элементам, не являющимся валидными.
- Если пользователь пытается отправить данные, браузер заблокирует форму и выведет сообщение об ошибке.
Примечание: Существует ошибки, которые не позволяют отправлять форму, в частности , , или , , или , , , или .
Валидация формы регистрации
Сразу приведу полный код валидации, а потом разберем его
jQuery(function($) { $('#register').on('submit', function(event) { if ( validateForm() ) { // если есть ошибки возвращает true event.preventDefault(); } }); function validateForm() { $(".text-error").remove(); // Проверка логина var el_l = $("#login"); if ( el_l.val().length < 4 ) { var v_login = true; el_l.after('<span class="text-error for-login">Логин должен быть больше 3 символов</span>'); $(".for-login").css({top: el_l.position().top + el_l.outerHeight() + 2}); } $("#login").toggleClass('error', v_login ); // Проверка e-mail var reg = /^\w+(?\w+)*@(((({2,})|(+)))|(+?))++\.({2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/i; var el_e = $("#email"); var v_email = el_e.val()?false:true; if ( v_email ) { el_e.after('<span class="text-error for-email">Поле e-mail обязательно к заполнению</span>'); $(".for-email").css({top: el_e.position().top + el_e.outerHeight() + 2}); } else if ( !reg.test( el_e.val() ) ) { v_email = true; el_e.after('<span class="text-error for-email">Вы указали недопустимый e-mail</span>'); $(".for-email").css({top: el_e.position().top + el_e.outerHeight() + 2}); } $("#email").toggleClass('error', v_email ); // Проверка паролей var el_p1 = $("#pass1"); var el_p2 = $("#pass2"); var v_pass1 = el_p1.val()?false:true; var v_pass2 = el_p1.val()?false:true; if ( el_p1.val() != el_p2.val() ) { var v_pass1 = true; var v_pass2 = true; el_p1.after('<span class="text-error for-pass1">Пароли не совпадают!</span>'); $(".for-pass1").css({top: el_p1.position().top + el_p1.outerHeight() + 2}); } else if ( el_p1.val().length < 6 ) { var v_pass1 = true; var v_pass2 = true; el_p1.after('<span class="text-error for-pass1">Пароль должен быть не менее 6 символов</span>'); $(".for-pass1").css({top: el_p1.position().top + el_p1.outerHeight() + 2}); } $("#pass1").toggleClass('error', v_pass1 ); $("#pass2").toggleClass('error', v_pass2 ); return ( v_login || v_email || v_pass1 || v_pass2 ); } });
Данный код будет корректно работать при обычной отправке формы. Для проверки формы, которая будет отправляться через ajax код скрипта (не валидация, а обработчик нажатия кнопки) будет немного отличаться:
jQuery(function($) { $('#register').on('submit', function(event) { event.preventDefault(); // отменяем событие по умолчанию if ( validateForm() ) { // если есть ошибки возвращает true return false; // прерываем выполнение скрипта } // тут ajax запрос }); // тут функция валидации без изменений }
- Для логина зададим ограничение – минимальное количество символов в логине 4. Если условие не соблюдается, то под полем ввода логина выводим соответствующее сообщение, а самому полю присваиваем класс error.
- Для поля e-mail сначала проверяем на заполненность и, если в нем что то есть, делаем проверку на соответствие маске. Информация о ошибке выводится аналогично полю ввода логина.
- Для полей пароль и подтверждение пароля сначала проверяем на заполненность, и если в них что то есть, делаем проверку на равенство паролей. Информация о ошибке выводится аналогично полю ввода логина.
Добавляем CSS
Так как CSS стилизирование не основная тема сегодняшнего урока, мы не будем на этом останавливаться. Просто нам необходим этот CSS код, чтобы форма выглядела красиво и все блоки были на своих местах.
Создайте файл style.css, вставьте в него код ниже. Теперь форма с будущей jquery валидацией, выглядит потрясающе. Не так ли?
Body {
background: #efefef;
margin: 0;
padding: 0;
border: none;
text-align: center;
font: normal 13px Georgia, «Times New Roman», Times, serif;
color: #222;
}
#content {
width: 500px;
margin: 0 auto;
margin-bottom: 25px;
padding: 0;
text-align: left;
}
fieldset {
margin-top: 25px;
padding: 15px;
border: 1px solid #d1d1d1;
-webkit-border-radius: 7px;
-moz-border-radius: 7px;
border-radius: 7px;
}
fieldset legend {
font: normal 30px Verdana, Arial, Helvetica, sans-serif;
text-shadow: 0 1px 1px #fff;
letter-spacing: -1px;
color: #273953;
}
input, textarea {
padding: 3px;
}
label {
cursor: pointer;
}
.block {
display: block;
}
small {
letter-spacing: 1px;
font-size: 11px;
font-style: italic;
color: #9e9e9e;
}
.info {
text-align: left;
padding: 5px;
font-size: 11px;
color: #fff;
position: absolute;
display: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: -1px 1px 2px #a9a9a9;
-moz-box-shadow: -1px 1px 2px #a9a9a9;
box-shadow: -1px 1px 2px #a9a9a9;
}
.error {
background: #f60000;
border: 3px solid #d50000;
}
.correct {
background: #56d800;
border: 3px solid #008000;
}
.wrong {
font-weight: bold;
color: #e90000;
}
.normal {
font-weight: normal;
color: #222;
}
#send {
background: #3f5a81;
width: 100%;
border: 5px solid #0F1620;
font: bold 30px Verdana, sans-serif;
color: #fafafa;
text-shadow: 1px 1px 1px #0F1620;
-webkit-border-radius: 7px;
-moz-border-radius: 7px;
border-radius: 7px;
}
#send:hover {
background: #4d76b1;
border: 5px solid #253750;
color: #fff;
}
#send:active {
text-indent: -10px;
}
Css для формы регистрации
/** * Стилизуем placeholder */ ::-webkit-input-placeholder {color: #aaaaaa;} ::-moz-placeholder {color: #aaaaaa;} /* Firefox 19+ */ :-moz-placeholder {color: #aaaaaa;} /* Firefox 18- */ :-ms-input-placeholder {color: #aaaaaa;} input::-webkit-input-placeholder {opacity: 1; transition: opacity 0.3s ease;} input::-moz-placeholder {opacity: 1; transition: opacity 0.3s ease;} input:-moz-placeholder {opacity: 1; transition: opacity 0.3s ease;} input:-ms-input-placeholder {opacity: 1; transition: opacity 0.3s ease;} input:focus::-webkit-input-placeholder {opacity: 0; transition: opacity 0.3s ease;} input:focus::-moz-placeholder {opacity: 0; transition: opacity 0.3s ease;} input:focus:-moz-placeholder {opacity: 0; transition: opacity 0.3s ease;} input:focus:-ms-input-placeholder {opacity: 0; transition: opacity 0.3s ease;} /** * Основные стили */ body { background: url('https://codernote.ru/files/image/fon-1.png'); font: 14px/20px 'Open Sans', serif; } h1, h2, h3 { text-align: center; letter-spacing: -0.6px; } .form__wrapper { width: 40%; margin: 20px auto; } form#register { position: relative; background: #FFF; padding: 10px; border: 1px solid #a7a7a7; -webkit-border-radius:4px; -moz-border-radius:4px; border-radius: 4px; box-shadow: 1px 3px 10px 0px rgba(0, 0, 0, 0.10); } form#register div.fields { position: relative; line-height: 30px; margin-bottom: 15px; } form#register input, form#register input { width: 95%; outline: none; padding: 5px; border: 1px solid #a7a7a7; } form#register input:focus, form#register input:focus { border: 1px solid #2A900C; } form#register input.error, form#register input.error { border: 1px solid red; } form#register span.dot { position: absolute; color: red; line-height: 15px; right: 0; } form#register span.text-error { position: absolute; top: 0; left: 0; color: red; font-size: 10px; line-height: 10px; } form#register button { position: relative; margin-top: 15px; right: 0; text-decoration:none; text-align:center; padding:11px 32px; border:solid 1px #004F72; -webkit-border-radius:4px; -moz-border-radius:4px; border-radius: 4px; font-size: 14px; font-weight:bold; color:#E5FFFF; background-color:#3BA4C7; background-image: -moz-linear-gradient(top, #3BA4C7 0%, #1982A5 100%); background-image: -webkit-linear-gradient(top, #3BA4C7 0%, #1982A5 100%); background-image: -o-linear-gradient(top, #3BA4C7 0%, #1982A5 100%); background-image: -ms-linear-gradient(top, #3BA4C7 0% ,#1982A5 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1982A5', endColorstr='#1982A5',GradientType=0 ); background-image: linear-gradient(top, #3BA4C7 0% ,#1982A5 100%); -webkit-box-shadow:0px 0px 2px #bababa, inset 0px 0px 1px #ffffff; -moz-box-shadow: 0px 0px 2px #bababa, inset 0px 0px 1px #ffffff; box-shadow:0px 0px 2px #bababa, inset 0px 0px 1px #ffffff; }