JSF 和 PrimeFaces 的互斥输入字段
Mutually exclusive input fields with JSF and PrimeFaces
我有一个 PrimeFaces 应用程序,我想在其中使两个输入文本字段相互排斥:用户应填写其中一个字段,但不能同时填写两个字段。
在以下示例中,用户可以通过 phone 号码或电子邮件搜索联系人。
<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>
这是正确的做法吗?我关心的是:
- 可能的 "deadlock" 个问题,两个字段最终都被禁用
- 正在提交的整个表单 and/or 在 Ajax 请求中验证,当我只想更新输入字段的
disabled
状态时
- 缺少一些完成所有工作的预定义 PrimeFaces 控件:)
这在标准 JSF 中并非微不足道。 JSF 实用程序库 OmniFaces has a validator for exactly this purpose, the <o:validateOne>
.
<h:inputText id="email" ... />
<h:inputText id="phone" ... />
<o:validateOne components="email phone" />
但是,从 UX 的角度来看,您最好重新设计表单,为 select 类型提供一个 UISelectOne
组件,并为 UIInput
提供一个字段输入值。例如
<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
值应表示组名称,因此您可以在整个文档中输入多个 "only one"。
我有一个 PrimeFaces 应用程序,我想在其中使两个输入文本字段相互排斥:用户应填写其中一个字段,但不能同时填写两个字段。
在以下示例中,用户可以通过 phone 号码或电子邮件搜索联系人。
<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>
这是正确的做法吗?我关心的是:
- 可能的 "deadlock" 个问题,两个字段最终都被禁用
- 正在提交的整个表单 and/or 在 Ajax 请求中验证,当我只想更新输入字段的
disabled
状态时 - 缺少一些完成所有工作的预定义 PrimeFaces 控件:)
这在标准 JSF 中并非微不足道。 JSF 实用程序库 OmniFaces has a validator for exactly this purpose, the <o:validateOne>
.
<h:inputText id="email" ... />
<h:inputText id="phone" ... />
<o:validateOne components="email phone" />
但是,从 UX 的角度来看,您最好重新设计表单,为 select 类型提供一个 UISelectOne
组件,并为 UIInput
提供一个字段输入值。例如
<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
值应表示组名称,因此您可以在整个文档中输入多个 "only one"。