JSF a4j:设置'disabled'时commandButton不工作

时间:2010-02-03 17:02:54

标签: java jsf java-ee richfaces ajax4jsf

当我在a4j:commandButton上包含'disabled'属性时,不会执行按钮的操作。取消“禁用”属性会使其正常工作。我没有做任何特殊验证(我知道)并且没有看到任何验证错误消息。

以下是我页面的一部分:

<t:dataTable id="myTable"
             var="region"
             value="#{MyPageBackingBean.regions}"
             width="100%">

...

<a4j:commandButton value="Update"
                   action="#{region.doUpdate}"
                   oncomplete="alert('done');"
                   disabled="#{!empty region && region.messageEmpty}"
                   immediate="true"/>

...

</t:dataTable>

有什么想法吗?谢谢!

修改

我尝试在t:dataTable上设置preserveDataModel =“true”无效。

我还做了一个测试,它有一个a4j:commandButton和没有数据表的文本框,但是仍然没有触发支持bean动作:

      <h:form>
     <a4j:region>
        <a4j:outputPanel id="testregion">
        <h:messages id="messages"/>

                          <a4j:status>
                             <f:facet name="start">
                                <h:graphicImage value="/images/progress_indicator.gif"/>
                             </f:facet>
                          </a4j:status>

                       <h:inputTextarea
                             rows="5"
                             value="#{MyPageBackingBean.myValue}"
                             style="width:100%; border: 1px solid #99CCFF;">
                          <a4j:support event="onkeyup"
                                       reRender="testregion"
                                       eventsQueue="messageModificationQueue"
                                       ignoreDupResponses="true"
                                       requestDelay="500"/>
                       </h:inputTextarea>

                       <a4j:commandButton id="doDelete"
                                          value="Delete"
                                          action="#{MyPageBackingBean.dummy}"
                                          reRender="testregion"
                                          disabled="#{empty MyPageBackingBean.myValue}"/>
                    <h:outputText value="#{MyPageBackingBean.myValue}"/>
        </a4j:outputPanel>
     </a4j:region>
  </h:form>

以下是用于测试的新支持bean代码:

private String m_myValue = null;
   public String getMyValue()
   {
      return m_myValue;
   }
   public void setMyValue(String value)
   {
      m_myValue = value;
   }
   private String mystr2 = null;
   public String dummy()
   {
      mystr2 = "hello";
      return null;
   }

谢谢!

2 个答案:

答案 0 :(得分:5)

在HTML世界中,disabled属性会导致任何HTML输入元素的name - value属性对(inputselect,{{1 }}和textarea)没有被发送到服务器端。

在JSF世界中,button属性的存在被用于标识要在服务器端调用的bean操作。但是,在表单提交的应用请求值阶段,JSF还会检查组件的name(和disabled)属性是否在采取任何操作之前评估rendered

true这里是#{region}的迭代表行对象,默认情况下#{MyPageBackingBean.regions} getter返回isMessageEmpty()。在表单提交的新请求中,true显然是空的,有效地生成按钮#{MyPageBackingBean.regions}。那时JSF不会调用相关的动作。

到目前为止,您需要确保disabled在后​​续请求中返回完全相同的数据模型。最简单的修复方法是将#{MyPageBackingBean.regions} bean放在会话范围内,以便它不会在后续请求中重新初始化,但这也会产生更多的负面影响。另一个修复是重新排列数据模型加载,以便它在bean构造函数中发生。由于您已经在使用Tomahawk的MyPageBackingBean,因此您需要将其<t:dataTable>属性设置为preserveDataModel。有关使用数据表的更多提示,您可能会发现本文也很有用:Using Datatables

答案 1 :(得分:1)

关于a4j的disabled属性需要注意的另一件事:commandButton:如果disabled属性设置为true,那么按钮的onclick事件的ajax挂钩永远不会呈现到最终的HTML中。也就是说,你得到一个这样的按钮:

<input type="button" onclick="return false" ... />

而不是:

<input type="button" onclick="A4J.AJAX.Submit('....');return false" ... />

所以,如果你想做这样的事情:

  1. 使用已停用的a4j:按钮
  2. 呈现页面
  3. 根据用户互动在客户端启用a4j:按钮
  4. 点击a4j:按钮调用服务器端操作
  5. 然后你需要做这样的事情:

    1. 使用a4j:按钮渲染页面并禁用=“#{true}”
    2. 让用户交互触发重新呈现a4j:button with disabled =“#{false}”
    3. 点击a4j:按钮调用服务器端操作
    4. 这是一个简单的例子:

      <h:selectOneCheckbox value="#{myAction.booleanProperty}">
        <a4j:support event="onclick" reRender="button1" />
      </h:selectOneCheckbox>
      <a4j:commandButton id="button1" action="#{myAction.doSomething}" 
        disabled="#{myAction.booleanProperty eq false}" value="click me"
      />