Валидация в экранах
Бин ScreenValidation
используется для запуска валидации в экранах. Он имеет следующие методы:
-
validateUiComponents()
- используется при коммите изменений в экранахStandardEditor
,InputDialog
, иMasterDetailScreen
. Принимает коллекцию из компонентов или контейнер компонентов и возвращает ошибки валидации в этих компонентах – объектValidationErrors
. МетодvalidateUiComponents()
также может быть использован в произвольном экране. Например:@UiController("sample_DemoScreen") @UiDescriptor("demo-screen.xml") public class DemoScreen extends Screen { @Autowired private ScreenValidation screenValidation; @Autowired 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()
- accepts a screen and an entity and returns theValidationErrors
object. By default, it is used in theStandardEditor
,MasterDetailScreen
, and in the editor of theDataGrid
. Выполняет правила перекрестной проверки, установленные на поля сущности.Editor screens validate class-level constraints on the commit if the constraints include the
UiCrossFieldChecks
group and all attribute-level constraint checks are successful. You can disable this type of validation using thesetCrossFieldValidate()
method of the controller. ThevalidateCrossFieldRules()
method also can be used in an arbitrary screen.В качестве примера рассмотрим сущность
Event
, для которой можно определить аннотацию уровня класса@EventDate
, для проверки того, что дата Start date должна быть раньше даты End date.@JmixEntity @Table(name = "SAMPLE_EVENT") @Entity(name = "sample_Event") @EventDate(groups = {Default.class, UiCrossFieldChecks.class}) public class Event { @JmixGeneratedValue @Column(name = "ID", nullable = false) @Id private UUID id; @Column(name = "NAME") @InstanceName private String name; @Column(name = "START_DATE") @Temporal(TemporalType.TIMESTAMP) private Date startDate; @Column(name = "END_DATE") @Temporal(TemporalType.TIMESTAMP) private Date endDate; // ...
Определение аннотации выглядит следующим образом:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = EventDateValidator.class) public @interface EventDate { String message() default "Start date must be earlier than the end date"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
Вот класс
EventDateValidator
:public 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("sample_DemoScreen") @UiDescriptor("demo-screen.xml") public class DemoScreen extends Screen { @Autowired private ScreenValidation screenValidation; @Autowired protected Metadata metadata; @Autowired protected TimeSource timeSource; @Subscribe("validateDateBtn") public void onValidateDateBtnClick(Button.ClickEvent event) { Event demoEvent = metadata.create(Event.class); demoEvent.setName("Demo event"); demoEvent.setStartDate(timeSource.currentTimestamp()); demoEvent.setEndDate(DateUtils.addDays(demoEvent.getStartDate(), -1)); ValidationErrors errors = screenValidation.validateCrossFieldRules(this, demoEvent); if (!errors.isEmpty()) { screenValidation.showValidationErrors(this, errors); } } }
-
Методы
showUnsavedChangesDialog()
иshowSaveConfirmationDialog()
показывают диалоги с предупреждением о несохраненных изменениях либо с кнопками Yes и No, либо Save, Do not save, и Cancel. Используются в методеStandardEditor
preventUnsavedChanges(). Выбрать тип диалога можно с помощью свойства приложения jmix.ui.screen.use-save-confirmation.