несколько h: форм в пользовательском интерфейсе: повторение

#jsf #richfaces

#jsf #богатые интерфейсы

Вопрос:

Я пытаюсь создать несколько h: форм на странице, которые отображаются с помощью компонента ui: repeat. Если у меня есть только одна сгенерированная h: форма, все работает идеально. Если у меня будет несколько h: форм, будет работать только последняя h: форма! (Если я попытаюсь отправить другую форму, то через мой сервис будет передан последний, единственный null!)

 <ui:repeat var="element" value="#{myService.elementList}">



            <rich:simpleTogglePanel switchType="client"
                                    label="#{element.codeElement} - #{element.description}" 
                                    opened="#{myService.isUiSelected(element)}"
                                    onexpand="expand#{element.codeElement}()"
                                    oncollapse="collapse#{element.codeElement}()">



    <h:form id="newKindForm">
      <a:commandLink ajaxSingle="true" id="idLink" onclick="#{rich:component('newTargetPanel')}.show()">
       <a:commandButton id="myButton" 
                        value="new Form"
                    action="#{myService.newForm(element)}"/> 
       </a:commandLink>                
    </h:form>


    <rich:modalPanel id="newTargetPanel" autosized="true" width="450">
       <f:facet name="header">
         <h:outputText value="My Pannel Title" />
       </f:facet>
       <f:facet name="controls">
          <h:panelGroup>
             <h:graphicImage value="/img/close.png" 
                             id="hidelink"
                             styleClass="hidelink" />
                <rich:componentControl for="newTargetPanel" 
                                       attachTo="hidelink"
                                       operation="hide" 
                                       event="onclick" />
          </h:panelGroup>
       </f:facet>



<!-- THIS IS THE PROBLEMATIC FORM -->
<h:form>
     <a:include viewId="../myRepeatableForm.xhtml" />
</h:form>



</rich:modalPanel>



</ui:repeat>
  

Какое-то предложение?

Спасибо

Ответ №1:

вы можете содержать все в одной форме и использовать execute атрибут для отправки только тех элементов, которые вы хотите. вот так:

<h:form id="newKindForm" prependId="false">
<ui:repeat id="newKindRepeat" var="element"
value="#{myService.elementList}" varStatus="varStatus">
<h:panelGroup id="newKindPanel">
<a:commandButton id="myButton"
execute="newKindRepeat:#{varStatus.index}:newKindPanel"
onclick="#{rich:component('newTargetPanel')}.show()"
value="new Form"
action="#{myService.newForm(element)}"/>
</h:panelGroup>
</ui:repeat>
</h:form>

пожалуйста, обратите внимание на prependId h:form , id и varStatus ui:repeat execute , a:commandButton of, ,.

кстати, предположим, что это a: означает ajax4jsf, я бы не рекомендовал использовать CommandButton, вложенный в CommandLink.

Комментарии:

1. в этом случае, как контроллер узнает, какой экземпляр формы выбрать из коллекции? IOW, если ui:repeat имеет 7 итераций и поля каждой итерации называются одинаково (IOW не индексируются), не вносит ли это двусмысленности?

2. @amphibient что вы подразумеваете под «именованным»? если вы имеете в виду идентификаторы, то да, они должны быть уникальными для всего dom, и они есть. когда вы откроете исходный код html после отображения приведенного выше кода, вы увидите области (h: panelGroup) с идентификаторами newKingRepeat:0:newKindPanel , newKingRepeat:1:newKindPanel , newKingRepeat:2:newKindPanel и так далее… ui:repeat добавляет свой собственный идентификатор и текущий индекс к вложенным в него идентификаторам компонентов. execute="newKingRepeat:#{varStatus.index}:newKindPanel" часть решает, какой контент диапазона будет отправлен на сторону сервера.

Ответ №2:

Является ли #{MyService.elementList} списком? Если да, я не уверен, сработает ли это. Попробуйте использовать javax.faces.model.Вместо этого используется модель данных. Обязательно внимательно прочитайте документацию. Это работает примерно так:

 public Datamodel getElements(){
  if(elements == null)
      elements = new ListDataModel(getElementList()); 
    return elements;
}

public List<Element> getElementList(){
    elementList = foo(); // load the elements in your List like you did before
    return elementList;
}
  

на ваш взгляд: <ui:repeat var="element" value="#{myService.elements}">

Я не знаком с RichFaces, это единственное предложение, которое я могу сделать.

Комментарии:

1. это должно отлично работать со списком. использование Datamodel не является обязательным.