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.
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.
Anyone have a solution?
Sample 1Sample 2. date of validation means the date when the Referred Party has successfully validated his/her identity and fully completed the on-boarding procedures.
To do this, first select the cells you want to restrict. Then, go to Data > Data Tools > Data Validation. In the Allow box, select "Date" from the drop-down menu. Then, in the Data box, enter the minimum and maximum dates you want to allow.
However this validation does not happen concurrently with the other form validations.
A backing bean action method is indeed not intented to perform input validation.
Anyone have a solution?
Use the right tool for the job; use a normal Validator
.
@FacesValidator("dataRangeValidator")
public class DateRangeValidator implements Validator {
// ...
}
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>
(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!)
Where the dateRangeValidator
look like this:
@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));
}
}
}
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" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With