Проверка диапазона дат
Я хочу сравнить две даты (StartDate и EndDate) и проверить, находится ли одна перед другой. Самое простое решение - просто сделать это на подложке и" коротком замыкании " метода.
однако эта проверка не происходит одновременно с другими проверками формы. Например, если у меня есть другое поле, которое требует проверки (помимо дат) и имеет недопустимый ввод, я получу сообщение только для этого конкретного поля. Только если другие поля действительны, я буду получите проверку даты на основе резервного компонента.
У кого-нибудь есть решение?
3 ответов
однако эта проверка не происходит одновременно с другими проверками формы.
метод действия резервного компонента действительно не предназначен для выполнения проверки ввода.
у кого-нибудь есть решение?
Используйте правильный инструмент для работы; использовать обычный Validator
.
@FacesValidator("dataRangeValidator")
public class DateRangeValidator implements Validator {
// ...
}
проверка нескольких входных значений с одного валидатор в свою очередь, однако, действительно история отдельно. В принципе, вы должны захватывать / передавать другой компонент или его значение в validate()
реализация метода. В простейшей форме вы можете использовать <f:attribute>
для этого. Предполагая, что вы используете <p:calendar>
чтобы выбрать даты, вот конкретный пример начала:
<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!)
здесь 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 utility library OmniFaces, тогда вы также можете просто использовать его <o:validateOrder>
компонент. Требование может быть достигнуто следующим образом без необходимости пользовательского проверяющего элемента:
<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" />
Читайте также:
Если вы используете PrimeFaces, которые могут ограничить минимальную и максимальную даты. пользователь не смог выбрать больший диапазон это пример:
<p:calendar id="startDate" value="#{bean.startDate}" maxdate="#{bean.endDate}">
<p:ajax event="dateSelect" update="endDate"/>
</p:calendar>
<p:calendar id="endDate" value="#{bean.endDate}" mindate="#{bean.startDate}" disabled="#{empty bean.startDate}">
<p:ajax event="dateSelect" update="startDate"/>
</p:calendar>
поскольку решение BalusC работает только в том случае, если у вас есть один диапазон дат для проверки в форме, вот улучшение, чтобы разрешить несколько проверок диапазона дат:
-
добавить
<f:attribute>
к компоненту календаря endDate, где вы указываете имя атрибута привязки к компоненту startDate:<f:attribute name="bindingAttributeName" value="startDateComponent" />
-
затем в валидаторе:
String startDateBindingAttrName = (String) component.getAttributes().get("bindingAttributeName"); UIInput startDateComponent = (UIInput) component.getAttributes().get(startDateBindingAttrName);