JSF a4j: commandButton не работает, когда установлено «отключено» - PullRequest
2 голосов
/ 03 февраля 2010

Когда я включаю атрибут «disabled» в 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>

Есть идеи?Спасибо!

Редактировать:

Я попытался установить preserveDataModel = "true" для t: dataTable безрезультатно.

Я также сделал тестимеющий a4j: commandButton и текстовое поле без таблицы данных, но действие вспомогательного компонента все еще не запускается:

      <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>

Вот новый код вспомогательного компонента, используемый для тестирования:

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 ]

5 голосов
/ 03 февраля 2010

В мире HTML атрибут disabled приводит к тому, что пара атрибутов name - value любого элемента ввода HTML (input, select, textarea и button) не отправляется на серверная сторона.

В мире JSF наличие атрибута name используется для идентификации действия компонента, которое будет вызвано на стороне сервера. Однако на этапе применения значений запроса формы отправки JSF также проверяет, оценивает ли атрибут disabledrendered) компонента true, прежде чем предпринимать какие-либо действия.

Здесь #{region} представляет собой объект строки итерированной таблицы #{MyPageBackingBean.regions}, чей геттер isMessageEmpty() по умолчанию возвращает true. В новом запросе формы отправить #{MyPageBackingBean.regions}, по-видимому, пусто, что фактически делает кнопку disabled. JSF не будет вызывать соответствующее действие.

Кстати, вам нужно убедиться, что #{MyPageBackingBean.regions} возвращает точно такую ​​же модель данных в последующем запросе. Самое простое решение - поместить боб MyPageBackingBean в область действия сеанса, чтобы он не был повторно инициализирован в последующем запросе, но это также имеет больше негативных побочных эффектов. Другое исправление состоит в том, чтобы изменить загрузку модели данных так, чтобы это происходило в конструкторе компонентов. Поскольку вы уже используете Томагавк <t:dataTable>, вам нужно установить для его атрибута preserveDataModel значение true. Дополнительные советы по использованию таблиц данных также могут оказаться полезными для этой статьи: Использование таблиц данных .

1 голос
/ 07 апреля 2010

Еще одна вещь, которую следует отметить относительно свойства disabled для a4j: commandButton: если для свойства disabled установлено значение true, то перехват ajax для события onclick кнопки никогда не отображается в конечном HTML. То есть вы получаете такую ​​кнопку:

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

вместо этого:

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

Итак, если вы хотите сделать что-то вроде этого:

  1. Рендеринг страницы с отключенной a4j: кнопка
  2. Включить a4j: кнопка на стороне клиента в зависимости от взаимодействия с пользователем
  3. Нажмите кнопку a4j: для вызова действия на стороне сервера

Тогда вместо этого вам нужно будет сделать что-то вроде этого:

  1. Рендеринг страницы с кнопкой a4j: и отключенной = "# {true}"
  2. Пусть пользовательское взаимодействие вызовет повторный рендеринг кнопки a4j: with disabled = "# {false}"
  3. Нажмите кнопку a4j: для вызова действия на стороне сервера

Вот простой пример:

<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"
/>
...