【问题标题】:how to disable multiple h:inputtext fields in JSF如何在 JSF 中禁用多个 h:inputtext 字段
【发布时间】:2013-01-07 20:17:06
【问题描述】:

在我的主页(.xhtml)中,我在 JSF 页面中有 4 个 h:inputText 框和一个 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"/>

我的要求是:

  1. 在第一个输入字段中输入的数据应禁用其他输入字段(即 2、3、4)。
  2. 在第二个输入字段中输入的数据应禁用其他输入字段(即 1、3、4)。等等.. 注意:同时,如果用户在第 1 或第 2 或第 3 或第 4(用户动态)字段中输入数据,并在删除输入字段之前删除相同的数据,则应启用所有字段。 当我在点击“搜索”按钮后得到回复(空或非空数据响应)时,所有输入字段都应启用另一个搜索(现在用户可以在 4 个字段中的任何一个中输入数据)

【问题讨论】:

  • 您是否希望在用户为任何组件设置值时永久禁用其他组件?如果他将值传递给第一个组件并提交其他组件将被禁用?或者有一些可能性可以取消它们?请解释
  • @emka86。其他输入字段应该被禁用,直到我点击搜索按钮。一旦我得到回复,所有输入字段现在应该被启用(搜索数据取决于用户输入在任何字段上输入)。
  • 所以你应该在客户端脚本而不是服务器端执行此操作。这对你来说可能吗?
  • @emka86.是的,我们也可以从客户端进行。
  • 我在我的回答中添加了一些 JavaScript (jQuery) 函数的示例,它会做你的事情

标签: jsf


【解决方案1】:

如果您只想在 jsf 中执行此操作,只需添加一些 AJAX 调用。以下是一些建议:

添加到您的所有&lt;h:inputText 属性disabled,值为#{searchSettlementTransRequest.getDisabled('this_component_id')"。所以整个事情会是这样的:

<h:inputText id="someId1" value="#{searchSettlementTransRequest.someValue}" name="stlmt" disabled="#{searchSettlementTransRequest.getDisabled('someId1')}"/>

在您的 bean 处理此请求的下一个更改 settter 为 `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"/>

所以知道一个组件的值何时会改变,所有其他组件都将被禁用。但是在调用后启用它们是不可能的,因为如果没有客户端脚本,你就不能轻易地使它们在选择或获得焦点或任何东西时可用。

如果您想暂时禁用组件,例如,当用户键入一个组件时,其他所有组件都已禁用,但当他选择其中一些组件时,会启用该组件,而所有其他组件,包括他首先编写文本的组件,将被禁用。在这种情况下,更好的方法是为此使用客户端脚本,例如 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 }

这不是很复杂的方法,但应该可以。知道当您开始输入一个组件时,其他组件将被禁用,但当您发送请求时,所有组件都将再次启用。

【讨论】:

  • 上述“onkeyup”解决方案正在工作,但在以下场景中不如预期。假设如果用户输入第一个输入字段并将其删除(在单击搜索按钮之前),那么现在应该启用所有字段.
  • 所以更改 onkeyup 值,添加以下内容:if ($('#thisComponentId').val() &amp;&amp; $('#thisComponentId').val() == '') { // here set enable for all components } else { // here set disable for all other components }
  • 我尝试如下。但没有luck.onkeyup="if($('#stlmtTransId').val()!=null && $('#stlmtTransId').val() != ''){ $('#stlmtTransId' ).attr('disabled', false); }else{ $('#pmtTransId,#agencyId,#agentId').attr('disabled', true); }"
  • 但是您的组件的 ID 是“stlID”而不是您的代码中的“stlmtTransId”?这只是拼写错误会解决您的问题吗?在 jQuery 函数中,您必须使用 &lt;h:inputText 属性中的值 id 所以:stlID',pmtID,AgentID` 和 AgencyID 不是 Bean 或 setter 方法中字段的名称。
  • 在运行文件中,映射到正确的 Ids(仅在发布时出现拼写错误)。第一次启用所有输入字段,一旦我输入任何字段,其他字段总是被禁用(第一个输入的字段始终保持可编辑状态)。
【解决方案2】:

如果您希望在每次页面加载后启用输入,您可以设置一个表示页面已加载的标志,并在每次通过侦听器发出 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。

干杯

【讨论】:

  • 根据您在问题中的评论更新了答案。此答案提供了使用服务器端的解决方案,如果您需要客户端解决方案,则此答案不合适。
  • @Cubbuk.my 字段是字符串。
  • @cubbuk.. 有什么用?
  • 它确保在其listener属性中的给定方法将在视图渲染之前执行。所以在这种情况下 searchSettlementTransRequest.preRenderView() 方法将在每个视图渲染之前执行。
猜你喜欢
  • 1970-01-01
  • 2015-06-24
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多