在我的主页(.xhtml),我在JSF页面中有4个h:input文本框和一个serach按钮(h:commandButton)
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt'>
<h:inputText id="pmtID" value="#{searchSettlementTransRequest.pmtTransId}" name='pmt'>
<h:inputText id="AgentID" value="#{searchSettlementTransRequest.AgentId}" name='agnt'>
<h:inputText id="AgencyID" value="#{searchSettlementTransRequest.AgencyId}" name='agncy'>
<h:commandButton id="tranSearchBtn" styleClass="valign first button-search sSearch" action="stlmtSubmit"/>
我的要求是:
- 在第一个输入字段中输入的数据上,应禁用其他输入字段(即 2,3,4)。
- 在第二个输入字段中输入的数据时,应禁用其他输入字段(即 1,3,4)。 等等..注意:同时,如果用户在第 1 个或第 2 个或第 3 个或第 4 个(用户动态)字段中输入数据并在省略输入字段之前删除相同的数据,在这种情况下,应启用所有字段。当我在单击"搜索"按钮后得到响应(空或非空数据响应)时,现在所有输入字段都应启用以进行另一个搜索(现在用户可以在 4 个字段中的任何字段中输入数据)
每次页面加载后启用输入,则可以有一个表示页面加载的标志,并在每次通过侦听器发出ajax请求后将该标志设置为false。为了确保在完成页面加载后将标志设置为 true,您可以使用preRenderView
事件。您只需要为preRenderView
事件执行一个方法,如果页面是通过完整请求而不是 ajax 请求加载的,则将标志设置为 true。如果页面加载了 ajax 请求,faces-request
参数将设置为"partial/ajax"。
public static final String INITIAL_VALUE = ""; // I assume your fields are integer and they are initialized to INITIAL_VALUE in the first place
public Boolean pageIsLoadedWithFullRequest = true;
public void preRenderView()
{
//check whether the request is an ajax request or not
Map<String, String> requestHeaderMap = FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
if(!"partial/ajax".equals(requestHeaderMap.get("faces-request")))
{
pageIsLoadedWithFullRequest = true;
}
如果要在用户写入其中一个字段时禁用其他输入,则可以在 blur 事件后进行 ajax 调用以更改其他输入字段的状态,并在侦听器中将 pageIsLoadedWithFullRequest
标志设置为 false。
public void madeAjaxRequest()
{
pageIsLoadedWithFullRequest = false;
}
public Boolean getStlIDEnabled()
{
return pageIsLoadedWithFullRequest || !stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getPmtTransIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && !pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getAgentIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && !AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getAgencyIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && !AgencyId.equals(INITIAL_VALUE);
}
<f:event type="preRenderView" listener="#{searchSettlementTransRequest.preRenderView()}"/> <!--This will ensure that preRenderView method will be called right before rendering of the view ends -->
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt' disabled="#{not searchSettlementTransRequest.stlIDEnabled}"/>
<h:inputText id="pmtID" value="#{searchSettlementTransRequest.pmtTransId}" name='pmt' disabled="#{not searchSettlementTransRequest.pmtTransIdEnabled}"/>
<h:inputText id="AgentID" value="#{searchSettlementTransRequest.AgentId}" name='agnt' disabled="#{not searchSettlementTransRequest.AgentIdEnabled}"/>
<h:inputText id="AgencyID" value="#{searchSettlementTransRequest.AgencyId}" name='agncy' disabled="#{not searchSettlementTransRequest.AgencyIdEnabled}"/>
如果你想通过ajax禁用它们,你应该添加f:ajax命令并渲染所有这四个inputTexts。例:
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt' disabled="#{not searchSettlementTransRequest.stlIDEnabled}">
<f:ajax event="blur"
listener=#{searchSettlementTransRequest.madeAjaxRequest()}
execute="stlID pmtID AgentID AgencyID"
execute="stlID pmtID AgentID AgencyID"/>
</h:inputText>
不相关 将变量(如 AgentId、AgencyID)的第一个字母大写不是一个好的做法,最好将它们更改为 agentId 和 agencyID。
干杯
如果你只想在jsf中执行此操作,只需添加一些AJAX调用。以下是一些建议:
添加到所有<h:inputText
属性disabled
,值为 #{searchSettlementTransRequest.getDisabled('this_component_id')"
。所以整个事情看起来像这样:
<h:inputText id="someId1" value="#{searchSettlementTransRequest.someValue}" name="stlmt" disabled="#{searchSettlementTransRequest.getDisabled('someId1')}"/>
接下来,在您的 Bean 处理此请求更改器中,"stlmTransId, pmtTransId, AgentId, AgencyId",他们将标记正在设置此值:
public void setXXX(XXX xxx) {
// your actual code comes here and at the end set that this component was changed
actuallyChanged = id_of_input_text_component_corresponding_to_this_value_as_string;
}
当然,您必须将字段String actuallyChanged
添加到您的 bean 中。方法getDisabled(String compId)
将知道外观:
public String getDisabled(String compId) {
if (actuallyChanged.equals(compId)) {
return "";
else {
return "disabled";
}
}
对于所有组件,您还添加了如下所示的 AJAX 调用:
<f:ajax event="change" execute="@this" render="stlID pmtID AgentID AgencyID"/>
因此,知道何时一个组件的值将更改所有其他组件将被禁用。但是在调用后启用它们是不可能的,因为如果没有 cliend side 脚本,您就无法轻松地使它们在选择或获得焦点或任何东西上可用。
如果您想暂时禁用组件,例如当用户键入一个组件时,其他组件全部禁用,但是当他选择其中一些组件时,将启用此组件,而所有其他组件(包括他首先编写文本的组件)将被禁用。在这种情况下,更好的方法是使用客户端脚本,例如JavaScript。
更新以完全匹配您在 JavaScript 中的问题 (jQuery)
向所有组件添加一个事件,如下所示:
onkeyup="$('#thisComponentId').attr('disabled', false); $('#otherComponentId').attr('disabled', true); $('#otherComponentId').attr('disabled', true); "
评论后,您可以将其更改为:
onkeyup="if ($('#thisComponentId').val() && $('#thisComponentId').val() == '') { // here set enable for all components } else { // here set disable for all other components }
这不是非常复杂的方法,但它应该有效。知道当您开始输入一个组件时,其他组件将被禁用,但当您发送请求时,所有组件都将再次启用。