界面中的验证
ScreenValidation
bean 可以用来运行界面中的验证逻辑,有如下方法:
-
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()
- 接收界面和实体作为参数,返回ValidationErrors
对象。默认情况下,在StandardEditor
,MasterDetailScreen
以及DataGrid
的编辑界面使用。该方法可进行跨字段验证。如果编辑界面的约束中包含
UiCrossFieldChecks
并且所有的属性级别验证通过,则会在提交时,进行类级别约束的验证。可以使用控制器的setCrossFieldValidate()
方法禁用此类验证。另外,validateCrossFieldRules()
方法也可以用在任意界面中。举个例子,对于
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 应用程序属性选择对话框类型。