我想比较两个日期(StartDate和EndDate),并检查一个日期是否在另一个日期之前.最简单的解决方案是只在支持bean上执行此操作,然后短路"该方法.
I want to compare two dates (StartDate and EndDate) and check whether one is before the other. The simplest solution is to just do it on the backing bean and "short-circuit" the method.
但是,此验证不会与其他表单验证同时发生.例如,如果我有另一个需要验证的字段(日期除外)且输入无效,则我只会收到该特定字段的消息.仅当其他字段有效时,我才会基于后备bean获得日期验证.
However this validation does not happen concurrently with the other form validations. For example if I have another field that requires validation (besides the dates) and has invalid input, I will only get a message for that specific field. Only if the other fields are valid will I get the date validation based on the backing bean.
有人有解决办法吗?
推荐答案
但是此验证不会与其他表单验证同时发生.
后备bean动作方法确实不打算执行输入验证.
A backing bean action method is indeed not intented to perform input validation.
有人知道吗?
使用正确的工具完成工作;使用普通的 Validator .
Use the right tool for the job; use a normal Validator.
@FacesValidator("dataRangeValidator") public class DateRangeValidator implements Validator { // ... }使用单个验证器验证多个输入值反过来确实是一个故事.基本上,您应该将其他组件或其值捕获/传递到validate()方法实现中.以其最简单的形式,您可以为此使用<f:attribute>.假设您正在使用<p:calendar>来选择日期,这是一个具体的启动示例:
Validating multiple input values with a single validator is in turn however indeed a story apart. Basically, you should be grabbing/passing the other component or its value along into the validate() method implementation. In its simplest form, you could use <f:attribute> for this. Assuming that you're using <p:calendar> to pick dates, here's a concrete kickoff example:
<p:calendar id="startDate" binding="#{startDateComponent}" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" /> <p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true"> <f:validator validatorId="dateRangeValidator" /> <f:attribute name="startDateComponent" value="#{startDateComponent}" /> </p:calendar>(请注意binding属性,它使组件在EL作用域中完全以给定的变量名称提供;还请注意,此示例为原样,并且绝对不应将其绑定到Bean属性!)
(note the binding attribute, it makes the component available in the EL scope on exactly the given variable name; also note that this example is as-is and that you should absolutely not bind it to a bean property!)
dateRangeValidator的外观如下:
@FacesValidator("dateRangeValidator") public class DateRangeValidator implements Validator { @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value == null) { return; // Let required="true" handle. } UIInput startDateComponent = (UIInput) component.getAttributes().get("startDateComponent"); if (!startDateComponent.isValid()) { return; // Already invalidated. Don't care about it then. } Date startDate = (Date) startDateComponent.getValue(); if (startDate == null) { return; // Let required="true" handle. } Date endDate = (Date) value; if (startDate.after(endDate)) { startDateComponent.setValid(false); throw new ValidatorException(new FacesMessage( FacesMessage.SEVERITY_ERROR, "Start date may not be after end date.", null)); } } }
如果您碰巧使用了 JSF实用程序OmniFaces ,那么您也可以只使用其 <o:validateOrder>组件.无需自定义验证器即可实现以下要求:
If you happen to use JSF utility library OmniFaces, then you could also just use its <o:validateOrder> component. The requirement can be achieved as follows without the need for a custom validator:
<p:calendar id="startDate" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" /> <p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true" /> <o:validateOrder components="startDate endDate" />另请参见:
- JSF不会是否支持跨域验证,是否有解决方法?
- JSF doesn't support cross-field validation, is there a workaround?
See also:
更多推荐
日期范围验证
发布评论