Валидация форм
Обязательные для заполнения элементы
Элементы управления помечаются как обязательные с помощью метода
setRequired()
, аргументом которого является текст сообщения об ошибке, отображаемый, если
пользователь не заполнит его. Если аргумент не указан, используется
сообщение об ошибке по умолчанию.
Правила
Мы добавляем правила проверки к элементам управления с помощью
метода addRule()
. Первый параметр — это правило, второй — сообщение об ошибке, а третий — аргумент правила
проверки.
Правила валидации проверяются только в том случае, если пользователь заполнил элемент.
Nette поставляется с рядом предопределенных правил, имена которых
являются константами класса Nette\Forms\Form
. Мы можем применять эти
правила ко всем элементам:
константа | описание | аргументы |
---|---|---|
Required |
псевдоним setRequired() |
– |
Filled |
псевдоним setRequired() |
– |
Blank |
не должно быть заполнены | – |
Equal |
значение равно параметру | mixed |
NotEqual |
значение не равно параметру | mixed |
IsIn |
значение равно некоторому элементу массива | array |
IsNotIn |
значение не равно ни одному элементу массива | array |
Valid |
ввод проходит валидацию (для Условия) | – |
Текстовые вводы
Для элементов addText()
, addPassword()
, addTextArea()
,
addEmail()
, addInteger()
, addFloat()
также могут быть применены
некоторые из следующих правил:
MinLength |
минимальная длина строки | int |
MaxLength |
максимальная длина строки | int |
Length |
длина в диапазоне или точная длина | пара [int, int] или int |
Email |
действительный адрес электронной почты | – |
URL |
действительный URL | – |
Pattern |
соответствует регулярному шаблону | string |
PatternInsensitive |
как Pattern , но без учёта регистра. |
string |
Integer |
целое число | – |
Numeric |
псевдоним Integer |
– |
Float |
целое число или число с плавающей точкой | – |
Min |
минимум целочисленного значения | int|float |
Max |
максимум целочисленного значения | int|float |
Range |
значение в диапазоне | пара [int|float, int|float] |
Правила Integer
, Numeric
и Float
автоматически
преобразуют значение в целое (или плавающее соответственно). Более
того, правило URL
также принимает адрес без схемы (например,
nette.org
) и дополняет схему (https://nette.org
). Выражения в
Pattern
и PatternInsensitive
должны быть действительны для всего
значения, т. е. как если бы оно было обернуто в символы ^
и
$
.
Количество предметов
Для элементов addMultiUpload()
, addCheckboxList()
, addMultiSelect()
также можно использовать следующие правила для ограничения
количества выбранных элементов или загруженных файлов:
MinLength |
минимальное количество | int |
MaxLength |
максимальное количество | int |
Length |
число в диапазоне или точное число | пары [int, int] или int |
Загрузка файлов
Для элементов управления addUpload()
, addMultiUpload()
также могут
быть использованы следующие правила:
MaxFileSize |
Максимальный размер файла в байтах | int |
MimeType |
Тип MIME, принимает подстановочные знаки ('video/*' ) |
string|string[] |
Image |
загруженный файл является JPEG, PNG, GIF, WebP | – |
Pattern |
имя файла соответствует регулярному выражению | string |
PatternInsensitive |
как Pattern , но без учета регистра. |
string |
Для MimeType
и Image
требуется расширение PHP fileinfo
.
Принадлежность файла или изображения к нужному типу определяется по
его сигнатуре. Целостность всего файла не проверяется. Вы можете
узнать, не повреждено ли изображение, например, попытавшись загрузить его.
Сообщения об ошибках
Все предопределенные правила, кроме Pattern
и PatternInsensitive
,
имеют сообщение об ошибке по умолчанию, поэтому их можно опустить.
Однако, передав и сформулировав все индивидуальные сообщения, вы
сделаете форму более удобной для пользователя.
Вы можете изменить сообщения по умолчанию в configuration, изменяя тексты в массиве
Nette\Forms\Validator::$messages
или используя translator.
В тексте сообщений об ошибках можно использовать следующие символы подстановки:
%d |
постепенно заменяет правила после аргументов |
%n$d |
заменяется на n-й аргумент правила |
%label |
заменяет на метку поля (без двоеточия) |
%name |
заменяет имя поля (например, name ) |
%value |
заменяется значением, введенным пользователем |
Условия
Помимо правил валидации, можно задать условия. Они устанавливаются
так же, как и правила, но мы используем addRule()
вместо
addCondition()
и, конечно, оставляем их без сообщения об ошибке
(условие просто спрашивает):
Условие может быть привязано к элементу, отличному от текущего, с
помощью addConditionOn()
. Первый параметр — это ссылка на поле. В
следующем случае электронная почта потребуется только в том случае,
если флажок установлен (т. е. его значение равно true
):
Условия могут быть сгруппированы в сложные структуры с помощью
методов elseCondition()
и endCondition()
.
В Nette очень легко реагировать на выполнение или невыполнение условия
на стороне JavaScript, используя метод toggle()
, см. Динамический JavaScript.
Ссылка на другой элемент
В качестве аргумента для правила или условия можно также передать
другой элемент формы. Тогда правило будет использовать значение,
введенное позже пользователем в браузере. Это можно использовать,
например, для динамической проверки того, что элемент password
содержит ту же строку, что и элемент password_confirm
:
Пользовательские правила и условия
Иногда мы сталкиваемся с ситуацией, когда встроенных правил валидации в Nette недостаточно, и нам нужно проверить данные от пользователя по-своему. В Nette это очень просто!
Вы можете передать любой обратный вызов в качестве первого параметра
в методы addRule()
или addCondition()
. Обратный вызов принимает сам
элемент в качестве первого параметра и возвращает булево значение,
указывающее на успешность проверки. При добавлении правила с помощью
addRule()
можно передать дополнительные аргументы, которые
передаются в качестве второго параметра.
Таким образом, пользовательский набор валидаторов может быть создан как класс со статическими методами:
Далее использование очень простое:
Пользовательские правила валидации также могут быть добавлены в
JavaScript. Единственным требованием является то, что правило должно быть
статическим методом. Его имя для валидатора JavaScript создается путем
соединения имени класса без обратных косых черт \
,
подчеркивания _
и имени метода. Например, запишите
App\MyValidators::validateDivisibility
как AppMyValidators_validateDivisibility
и добавьте
его в объект Nette.validators
:
Событие onValidate
После отправки формы проверка выполняется путем проверки отдельных
правил, добавленных с помощью addRule()
, и последующего вызова события onValidate
. Его обработчик
может быть использован для дополнительной проверки, обычно для
проверки правильности комбинации значений в нескольких
элементах формы.
Если обнаружена ошибка, она передается в форму с помощью метода
addError()
. Это может быть вызвано как на определенном элементе, так
и непосредственно на форме.
Ошибки обработки
Во многих случаях мы обнаруживаем ошибку, когда обрабатываем
действительную форму, например, когда мы записываем новую запись в
базу данных и сталкиваемся с дублирующимся ключом. В этом случае мы
передаем ошибку обратно в форму с помощью метода addError()
. Это
может быть вызвано как на определенном элементе, так и непосредственно
на форме:
Если возможно, мы рекомендуем добавить ошибку непосредственно в элемент формы, так как она будет отображаться рядом с ним при использовании рендеринга по умолчанию.
Вы можете вызывать addError()
несколько раз, чтобы передать
несколько сообщений об ошибках форме или элементу. Вы получаете их с
помощью функции getErrors()
.
Обратите внимание, что $form->getErrors()
возвращает сводку всех
сообщений об ошибках, даже тех, которые были переданы непосредственно
отдельным элементам, а не только непосредственно форме. Сообщения об
ошибках, переданные только форме, извлекаются через
$form->getOwnErrors()
.
Изменение входных значений
Используя метод addFilter()
, мы можем изменить значение, введенное
пользователем. В этом примере мы будем допускать и удалять пробелы в
почтовом индексе:
Фильтр включен между правилами проверки и условиями и поэтому
зависит от порядка следования методов, то есть фильтр и правило
вызываются в том же порядке, что и порядок следования методов
addFilter()
и addRule()
.
Валидация JavaScript
Язык правил и условий проверки является мощным. Несмотря на то, что
все конструкции работают как на стороне сервера, так и на стороне
клиента, в JavaScript. Правила передаются в HTML-атрибутах data-nette-rules
в
виде JSON. Сама валидация обрабатывается другим скриптом, который
перехватывает все события формы submit
, перебирает все вводимые
данные и запускает соответствующие валидации.
Этот скрипт — netteForms.js
, который доступен из нескольких
возможных источников:
Вы можете встроить сценарий непосредственно в HTML-страницу из CDN:
Или скопируйте локально в общую папку проекта (например, с сайта
vendor/nette/forms/src/assets/netteForms.min.js
):
Или установите через npm:
А затем загрузите и запустите:
Кроме того, вы можете загрузить его непосредственно из папки
vendor
:
Динамический JavaScript
Вы хотите отображать поля адреса только в том случае, если
пользователь решит отправить товар по почте? Нет проблем. Ключом
является пара методов addCondition()
и toggle()
:
Этот код говорит, что при выполнении условия, то есть при установке
флажка, HTML-элемент #address-container
станет видимым. И наоборот. Итак, мы
помещаем элементы формы с адресом получателя в контейнер с этим ID, и
при нажатии на флажок они скрываются или показываются. Этим занимается
скрипт netteForms.js
.
Любой селектор может быть передан в качестве аргумента методу
toggle()
. По историческим причинам буквенно-цифровая строка без
других специальных символов рассматривается как идентификатор
элемента, так же как если бы ей предшествовал символ #
. Второй
необязательный параметр позволяет нам изменить поведение, т. е. если бы
мы использовали toggle('#address-container', false)
, элемент отображался бы
только при снятом флажке.
Реализация JavaScript по умолчанию изменяет свойство hidden
для
элементов. Однако мы можем легко изменить поведение, например, добавив
анимацию. Просто переопределите метод Nette.toggle
в JavaScript с помощью
собственного решения:
Отключение валидации
В некоторых случаях необходимо отключить валидацию. Если кнопка submit
не должна выполнять проверку после отправки (например, кнопка
Отмена или Предварительный просмотр), вы можете отключить
проверку, вызвав $submit->setValidationScope([])
. Вы также можете проверить
форму частично, указав элементы для проверки.
Событие onValidate на форме вызывается всегда и не
зависит от setValidationScope
. Событие onValidate
на контейнере
вызывается только тогда, когда этот контейнер указан для частичной
валидации.