3

我在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第二个日期发送的输出是:

2013 年 10 月 10 日星期四 00:00:00 CEST

无效的

提交时间 2013 年 10 月 10 日星期四 00:00:00 CEST 2013 年 10 月 12 日星期六 00:00:00 CEST

这表明f:attribute标签不适用于p:calendar组件,因为它适用于其他输入组件。但是,我可以通过视图根访问第一个日历,但强制我知道要验证的组件的客户端 ID 的整个路径。这两个值都是稍后在托管 bean 中设置的,没有问题。

一种解决方法是在第一个日期更改时使用 ajax 调用,以便将其放置在模型中并将其作为日期本身发送,f:attribute而不是发送 UIInput(我已经这样做了)。

没有更好的方法吗?也许我必须像在这种情况下将它们加入单个组件中?

4

2 回答 2

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>

也可以看看:

于 2013-10-30T13:10:32.600 回答
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并处理它们。

于 2017-05-30T16:12:33.610 回答