#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 не является обязательным.