我在 JSF 2 中有一个表单,我在其中使用双字段来指定日期范围。其目的不是让用户选择第二个日期之前的第一个日期。所以我想在使用p:calendar
组件发送表单之前执行验证。我所做的是将验证器绑定到第二个日历输入,以便在内部访问第一个组件并比较日期。
这是我的 xhtml 页面:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:form id="date_form">
<p:calendar id="date1input" value="#{dateTestBean.date1}" />
<p:calendar value="#{dateTestBean.date2}" validator="dateValidator">
<f:attribute name="date1" value="#{date1input}" />
</p:calendar>
<p:commandButton value="Submit" action="#{dateTestBean.submit}"
ajax="false" />
</h:form>
</h:body>
</html>
我的托管bean:
@ManagedBean
@ViewScoped
public class DateTestBean {
private Date date1;
private Date date2;
public Date getDate1() {
return date1;
}
public void setDate1(Date date1) {
this.date1 = date1;
}
public Date getDate2() {
return date2;
}
public void setDate2(Date date2) {
this.date2 = date2;
}
public void submit() {
System.out.println("Submited " + date1 + " " + date2);
}
}
我的验证员类:
@FacesValidator(value = "dateValidator")
public class DateValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
System.out.println(((UIInput) context.getViewRoot().findComponent(
"date_form:date1input")).getValue());
UIInput date = (UIInput) component.getAttributes().get("date1");
System.out.println(date);
//Will perform date comparison
}
}
我在这里发送的输出2013-10-10
作为第一个日期而2013-10-12
作为第二个日期发送:
星期四10月10日00:00:00 CEST 2013
空
提名截止日期10月10日00:00:00 CEST 2013年10月12日星期六00:00:00 CEST 2013
这表明f:attribute
标记不适用于p:calendar
组件as it does for other input components。但是,我可以通过视图根访问第一个日历,但强制我知道要验证的组件的客户端ID的完整路径。这两个值稍后在托管bean中设置,没有任何问题。
解决方法是to use an ajax call when first date changes,以便将其放在模型中,并将其作为日期本身发送到f:attribute
,而不是发送UIInput(我已经这样做了)。 / p>
有没有更好的方法?也许我必须将它们加入到this case中的单个组件中?
答案 0 :(得分:2)
从您的代码中
<p:calendar id="date1input" ... />
<p:calendar ...>
<f:attribute name="date1" value="#{date1input}" />
</p:calendar>
#{date1input}
未代表id="date1input"
。如这些代码示例所示,它由binding="#{date1input}"
表示。
相应修复:
<p:calendar binding="#{date1input}" ... />
<p:calendar ...>
<f:attribute name="date1" value="#{date1input}" />
</p:calendar>
答案 1 :(得分:1)
另一种解决方案是在启动时将值设置为null,并在组件的初始状态下禁用第二个日历,并将其mindate
设置为第一个日历的值。
<p:calendar
id="startdate"
value="#{bean.startdate}">
<p:ajax
event="dateSelect"
listener="#{origemBean.listener}"
update="@form" />
</p:calendar>
<p:calendar
id="enddate"
disabled="#{empty bean.startdate}"
value="#{bean.enddate}"
mindate="#{bean.startdate}">
<p:ajax
event="dateSelect"
listener="#{bean.listener}"
update="@form" />
</p:calendar>
在托管bean上,只需验证startdate
是否在enddate
之后并对其进行处理。