Валидатор предназначен для проверки значения, введенного в визуальном компоненте.
Следует отличать валидацию от проверки типа данных. Если для некоторого компонента, например
TextField, задан тип, отличный от строкового (это происходит при
связывании с атрибутом сущности или назначении datatype
), то компонент не позволяет ввести
значение, не удовлетворяющее этому типу - при потере фокуса или нажатии Enter
компонент отобразит предыдущее значение.
Валидация же срабатывает не сразу при вводе или потере компонентом фокуса, а только при вызове у компонента
метода validate()
. Это означает, что компонент (и связанный с ним атрибут сущности) может
некоторое время содержать значение, не удовлетворяющее условиям валидации. Это не является проблемой, так как
обычно компоненты ввода с валидацией располагаются в экране редактирования,
а он автоматически вызывает валидацию всех своих компонентов перед коммитом. Если же компонент находится не в
экране редактирования, то необходимо вызывать его метод validate()
в контроллере явно.
В XML-дескрипторе экрана валидатор для компонента может быть задан во вложенном элементе
validator
. Возможные атрибуты элемента validator
:
-
script
− путь к скрипту Groovy, осуществляющему валидацию. -
class
− имя класса Java, реализующего интерфейсField.Validator
. -
Groovy-валидатор и стандартные классы Java-валидаторов, расположенные в пакете
com.haulmont.cuba.gui.components.validators
поддерживают атрибутmessage
− сообщение, выводимое пользователю в случае ошибки валидации. Атрибут должен содержать сообщение или ключ в пакете сообщений экрана, например:<validator class="com.haulmont.cuba.gui.components.validators.PatternValidator" message="msg://validationError" pattern="\d{3}"/>
# messages.properties validationError = Input error
Выбор механизма валидации осуществляется следующим образом:
-
Если не указано значение атрибута
script
, и сам элементvalidator
не содержит текста выражения Groovy, то в качестве валидатора используется класс, указанный в атрибутеclass
. -
Если элемент
validator
содержит текст, то он будет использован как выражение Groovy и выполнен с помощью Scripting. -
В противном случае с помощью Scripting будет выполнен скрипт Groovy, указанный в атрибуте
script
.
В выражение или скрипт Groovy будет передана одна переменная value
, содержащая значение,
введенное в визуальном компоненте. Выражение или скрипт должны вернуть boolean
значение:
true
− valid, false
− not valid.
Если в качестве валидатора используется класс Java, то он должен иметь либо дефолтный конструктор без параметров, либо конструктор со следующим набором параметров:
-
org.dom4j.Element
,String
- в этот конструктор будут переданы XML-элемент валидатора и имя пакета сообщений экрана. -
org.dom4j.Element
- в этот конструктор будет передан XML-элемент валидатора.
Если валидатор реализован внутренним классом, то он должен быть объявлен с модификатором static
,
а его имя для загрузки отделяется символом "$", например:
<validator class="com.sample.sales.gui.AddressEdit$ZipValidator"/>
Платформа уже содержит несколько реализаций наиболее часто используемых валидаторов (см. пакет
com.haulmont.cuba.gui.components.validators
), которые можно применять в проектах:
-
DateValidator
-
DoubleValidator
-
EmailValidator
-
IntegerValidator
-
LongValidator
-
PatternValidator
-
ScriptValidator
Валидатор-класс можно назначить компоненту не только в XML-дескрипторе экрана, но и программно, передавая
экземпляр валидатора в метод addValidator()
компонента.
Пример создания класса валидатора почтового индекса:
public class ZipValidator implements Field.Validator { @Override public void validate(Object value) throws ValidationException { if (value != null && ((String) value).length() != 6) throw new ValidationException("Zip must be of 6 characters length"); } }
Использование валидатора почтового индекса и стандартного валидатора по шаблону в полях компонента FieldGroup:
<fieldGroup> <field id="zip" required="true"> <validator class="com.company.sample.gui.ZipValidator"/> </field> <field id="imei"> <validator class="com.haulmont.cuba.gui.components.validators.PatternValidator" pattern="\d{15}" message="IMEI validation failed"/> </field> </fieldGroup>
Пример программного задания валидатора:
if (Boolean.TRUE.equals(parameter.getRequired())) { tokenList.addValidator(new Field.Validator() { @Override public void validate(Object value) throws ValidationException { if (value instanceof Collection && CollectionUtils.isEmpty((Collection) value)) { throw new ValidationException(getMessage("paramIsRequiredButEmpty")); } } }); }