JSF和PrimeFaces的互斥输入字段

时间:2016-06-03 15:57:38

标签: validation jsf jsf-2 primefaces

我有一个PrimeFaces应用程序,我想让两个输入文本字段互斥:用户应填写任一字段,但不能同时填写两者。

在以下示例中,用户可以通过电话号码或电子邮件搜索联系人。

<h:form>
    <h:outputLabel>Phone Number:
        <h:inputText id="phoneInput" value="#{contactSearch.phone}"
                     disabled="#{not empty contactSearch.email}">
            <p:ajax event="keyup" update="emailInput"/>
        </h:inputText>
    </h:outputLabel>
    <h:outputLabel>Email Address:
        <h:inputText id="emailInput" value="#{contactSearch.email}"
                     disabled="#{not empty contactSearch.phone}">
            <p:ajax event="keyup" update="phoneInput"/>
        </h:inputText>
    </h:outputLabel>

    <!-- Possibly other fields... -->

    <h:commandButton value="Search" action="#{contactSearch.search}"/>
</h:form>

这是正确的方法吗?我担心:

  • 可能&#34;死锁&#34;两个字段最终被禁用的问题
  • 当我只想更新输入字段的disabled状态时,在Ajax请求中提交和/或修改的整个表单
  • 缺少一些预先完成所有工作的预定义PrimeFaces控件:)

1 个答案:

答案 0 :(得分:3)

这在标准JSF中并非无足轻重。 JSF实用程序库Official user guide具有用于此目的的验证器OmniFaces

<h:inputText id="email" ... />
<h:inputText id="phone" ... />
<o:validateOne components="email phone" />

但是,从<o:validateOne>角度来看,您最好重新设计表单,以提供单个UISelectOne组件来选择类型,并使用单个UIInput字段来输入值。 E.g。

<h:selectOneRadio ... value="#{bean.type}">
    <f:selectItem itemValue="email" />
    <f:selectItem itemValue="phone" />
</h:selectOneRadio>
<h:inputText ... value="#{bean.value}" />

更新:由于服务器端验证价格不合理,而且你真的想在没有太多ajax流量的情况下禁用另一个,你唯一的选择是使用纯JavaScript / jQuery来完成工作(如果必须与服务器端验证结合使用作为后备)。

这是一种基于jQuery的通用方法:

<h:inputText styleClass="onlyone" a:data-onlyone="groupName" />
<h:inputText styleClass="onlyone" a:data-onlyone="groupName" />
...

$(document).on("input", ":input.onlyone", function() {
    var $this = $(this);
    var $others = $("[data-onlyone='" + $this.data("onlyone") + "']").not($this);
    $others.val(null).attr("disabled", !!$this.val());
});

data-onlyone值应代表组名,因此您可以在整个文档中拥有多个“仅一个”输入。