两个主要的日历组件验证

时间:2013-10-25 13:34:24

标签: jsf jsf-2 primefaces validation

我在 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中的单个组件中?

2 个答案:

答案 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之后并对其进行处理。