【问题标题】:Two primefaces calendar component validation两个 primefaces 日历组件验证
【发布时间】:2013-11-04 15:52:54
【问题描述】:

我在 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 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(我已经这样做了)。

没有更好的方法吗?也许我必须像this case 那样将它们加入到单个组件中?

【问题讨论】:

  • #{date1input} 不是指id="date1input",而是应该指binding="#{date1input}"。更仔细地检查这些示例。
  • Date range validation 的可能副本
  • 这是真的!我还没有看到,这是有道理的,因为您传递的是绑定组件的引用而不是 id 本身。但也强制您将其绑定,恕我直言,这是一个负面因素。最好的办法可能是实现一个基于双输入的组件并一次性验证它。
  • 关于你对使用binding的明显厌恶:仔细阅读this如何正确使用它。当被误解和误用时,它确实是邪恶的。至于“最佳”方法,您是否查看过链接副本中的 OmniFaces 方式?没有约束力,没有 f:attribute,没有其他混乱。只需一个&lt;o:validateOrder components="startDateId endDateId" /&gt; 标签即可。
  • 非常感谢@BalusC,Omnifaces 帮助我实现了这一目标。但是,当至少一个组件为空(NPE)时,它似乎会中断。我的组件不是必需的,如果它们都不为空,我只想检查它们的顺序。它似乎没有在文档中指定,在validateOrdervalidateAll 中也没有。无论如何,感谢您的贡献!

标签: jsf jsf-2 primefaces validation


【解决方案1】:

根据您的代码,

<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>

另见:

【讨论】:

    【解决方案2】:

    另一种解决方案是在启动时将值设置为 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 之后并处理它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-19
      • 2013-02-22
      • 2012-09-19
      • 2019-06-09
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2011-12-20
      相关资源
      最近更新 更多