3.5.1.7. Валидация в экранах
Бин ScreenValidation
может использоваться для запуска валидации в экранах. Он имеет следующие методы:
-
ValidationErrors validateUiComponents()
- используется при коммите изменений в экранахStandardEditor
,InputDialog
, иMasterDetailScreen
. Принимает на вход коллекцию из компонентов или контейнер компонентов и возвращает ошибки валидации в этих компонентах (объектValidationErrors
). МетодvalidateUiComponents()
также может быть использован в произвольном экране. Например:@UiController("demo_DemoScreen") @UiDescriptor("demo-screen.xml") public class DemoScreen extends Screen { @Inject private ScreenValidation screenValidation; @Inject private Form demoForm; @Subscribe("validateBtn") public void onValidateBtnClick(Button.ClickEvent event) { ValidationErrors errors = screenValidation.validateUiComponents(demoForm); if (!errors.isEmpty()) { screenValidation.showValidationErrors(this, errors); return; } } }
-
showValidationErrors()
- показывает нотификацию со всеми ошибками и проблемными компонентами. Метод принимает на вход экран и объектValidationErrors
. Также используется по умолчанию в экранахStandardEditor
,InputDialog
, иMasterDetailScreen
. -
validateCrossFieldRules()
- принимает на вход экран и сущность и возвращает объектValidationErrors
. Выполняет правила перекрестной проверки, установленные на поля сущности. Экраны редактирования выполняют валидацию ограничений уровня класса при коммите, если ограничения включают группуUiCrossFieldChecks
, и все проверки ограничений уровня атрибутов прошли успешно (больше информации см. в разделе Собственные ограничения). Валидацию данного типа можно отключить с помощью метода контроллераsetCrossFieldValidate()
. По умолчанию используется в экранахStandardEditor
,MasterDetailScreen
, в редактореDataGrid
. МетодvalidateCrossFieldRules()
также может быть использован в произвольном экране.В качестве примера рассмотрим сущность
Event
, для которой мы можем определить аннотацию уровня класса, для проверки того, что дата Start date должна быть раньше даты End date.Сущность Event@Table(name = "DEMO_EVENT") @Entity(name = "demo_Event") @NamePattern("%s|name") @EventDate(groups = {Default.class, UiCrossFieldChecks.class}) public class Event extends StandardEntity { private static final long serialVersionUID = 1477125422077150455L; @Column(name = "NAME") private String name; @Temporal(TemporalType.TIMESTAMP) @Column(name = "START_DATE") private Date startDate; @Temporal(TemporalType.TIMESTAMP) @Column(name = "END_DATE") private Date endDate; ... }
Определение аннотации выглядит следующим образом:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = EventDateValidator.class) public @interface EventDate { String message() default "The Start date must be earlier than the End date"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
EventDateValidatorpublic class EventDateValidator implements ConstraintValidator<EventDate, Event> { @Override public boolean isValid(Event event, ConstraintValidatorContext context) { if (event == null) { return false; } if (event.getStartDate() == null || event.getEndDate() == null) { return false; } return event.getStartDate().before(event.getEndDate()); } }
Далее вы можете использовать метод
validateCrossFieldRules()
в произвольном экране.@UiController("demo_DemoScreen") @UiDescriptor("demo-screen.xml") public class DemoScreen extends Screen { @Inject protected Metadata metadata; @Inject protected ScreenValidation screenValidation; @Inject protected TimeSource timeSource; @Subscribe("validateBtn") public void onValidateBtnClick(Button.ClickEvent event) { Event event = metadata.create(Event.class); event.setName("Demo event"); event.setStartDate(timeSource.currentTimestamp()); // We make the endDate earlier than the startDate event.setEndDate(DateUtils.addDays(event.getStartDate(), -1)); ValidationErrors errors = screenValidation.validateCrossFieldRules(this, event); if (!errors.isEmpty()) { screenValidation.showValidationErrors(this, errors); } } }
-
showUnsavedChangesDialog()
- показывает стандартный диалог несохраненных изменений ("Вы действительно хотите закрыть экран?") с кнопками Да и Нет. Используется в экране редактораStandardEditor
. МетодshowUnsavedChangesDialog()
имеет обработчик, который реагирует на действия пользователя (кнопку, которую он нажал):screenValidation.showUnsavedChangesDialog(this, action) .onDiscard(() -> result.resume(closeWithDiscard())) .onCancel(result::fail);
-
showSaveConfirmationDialog()
- показывает стандартный диалог подтверждения сохранения измененных данных ("Сохранить изменения перед закрытием экрана?") с кнопками Сохранить, Не сохранять, Отмена. Используется в экране редактораStandardEditor
. МетодshowSaveConfirmationDialog()
имеет обработчик, который реагирует на действия пользователя (кнопку, которую он нажал):screenValidation.showSaveConfirmationDialog(this, action) .onCommit(() -> result.resume(closeWithCommit())) .onDiscard(() -> result.resume(closeWithDiscard())) .onCancel(result::fail);
Вы можете настроить тип диалога с помощью свойства приложения cuba.gui.useSaveConfirmation.