selectonemenu внутри таблицы в jsf2
у меня есть таблица с 2 компонентами selectOneMenu.
Я хотел бы, чтобы после того, как запись была выбрана в первом компоненте selectOneMenu, она обновит другой selectOneMenu с Ajax в той же строке.
мой стол:
<p:dataTable value="#{myBean.myInfo}" var="myInfo">
<p:column>
<f:facet name="header">Group</f:facet>
<h:selectOneMenu value="#{myInfo.myInfoType.code}">
<f:selectItems value="#{myBean.myList}" />
<f:ajax event="change" execute="@this" listener="#{myBean.refershNames}" render="myNames"/>
</h:selectOneMenu>
</p:column>
<p:column>
<f:facet name="header">Name</f:facet>
<h:selectOneMenu id="myNames" value="#{myInfo.myInfoType.secondCode}">
<f:selectItems value="#{myBean.mySecondList}" />
</h:selectOneMenu>
</p:column>
<p:dataTable>
в фасоли у меня:
List<SelectItem> myList,mySecondList;
public void refershNames(AjaxBehaviorEvent event){
//how can I retrieve the selected item and update the relevant record?
}
Как я могу сделать это с Ajax? Я использую JSF2
2 ответов
оберните значение datatable в DataModel<E>
, так что вы можете получить myInfo
объект в вопросе DataModel#getRowData()
. Итак,
DataModel<MyInfo> myInfoModel; // +getter
@PostConstruct
public void init() {
myInfo = myInfoDAO.list();
myInfoModel = new ListDataModel<MyInfo>(myInfo);
}
С
<h:dataTable value="#{myBean.myInfoModel}" var="myInfo">
и
public void refreshNames(AjaxBehaviorEvent event){
MyInfo myInfo = myInfoModel.getRowData();
// Get code and update secondCode.
}
обновление согласно комментариям, вот testcase, который я создал после того, как вы сказали, что он не работает. Он работал для меня с Mojarra 2.0.3 на Tomcat 7.0.5 и Glassfish 3.0.1.
com.example.Item
public class Item {
private String value1;
private String value2;
// Generate public getters/setters.
}
com.example.Bean
@ManagedBean
@ViewScoped
public class Bean {
private List<Item> items;
private DataModel<Item> model;
private List<String> list;
@PostConstruct
public void init() {
items = Arrays.asList(new Item(), new Item(), new Item());
model = new ListDataModel<Item>(items);
list = Arrays.asList("one", "two", "three");
}
public void change(AjaxBehaviorEvent e) {
Item item = model.getRowData();
item.setValue2(item.getValue1());
}
public DataModel<Item> getModel() {
return model;
}
public List<String> getList() {
return list;
}
}
test.xhtml
<h:form>
<h:dataTable value="#{bean.model}" var="item">
<h:column>
<h:selectOneMenu value="#{item.value1}">
<f:selectItem itemLabel="select..." itemValue="#{null}" />
<f:selectItems value="#{bean.list}" />
<f:ajax execute="@this" listener="#{bean.change}" render="list2" />
</h:selectOneMenu>
</h:column>
<h:column>
<h:selectOneMenu id="list2" value="#{item.value2}">
<f:selectItem itemLabel="select..." itemValue="#{null}" />
<f:selectItems value="#{bean.list}" />
</h:selectOneMenu>
</h:column>
</h:dataTable>
</h:form>
этот тестовый случай доказывает, что всякий раз, когда вы изменяете раскрывающееся значение в 1-м столбце, то раскрывающееся значение во 2-м столбце в той же строке будет отражено для получения того же значения.
у меня была та же проблема, и после многих проб и ошибок это сработало для меня
<p:column style="width:50%">
<f:facet name="header">
<h:outputText value="Criteria" />
</f:facet>
<h:selectOneMenu value="#{option.predefinedMessageId}"
valueChangeListener="#{predefinedMessageBean.predefinedMessageChangeListener}">
<f:selectItems
value="#{campaignRecipientCriteriaBean.messages}"
var="predef" itemLabel="#{predef.fieldName}"
itemValue="#{predef.predefinedMessageId}" />
<p:ajax event="change" update="optionsList"/>
</h:selectOneMenu>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Options" />
</f:facet>
<p:outputPanel id="optionsList">
<h:selectOneMenu
value="#{option.predefinedMessageOptionId}">
<f:selectItems
value="#{predefinedMessageBean.emptyOptionBeansList}"
var="predef" itemLabel="#{predef.optionCaption}"
itemValue="#{predef.predefinedMessageOptionId}" />
</h:selectOneMenu>
</p:outputPanel>
</p:column>
valuechangelistener составляет
public void predefinedMessageChangeListener(ValueChangeEvent e)
{
getPredefinedMessageOptions(Integer.parseInt(e.getNewValue().toString()));
}
Это просто и отлично работает для меня , так как сообщение, которое я выбираю в первом столбце, обновляет параметры во втором столбце и выполняется через ajax. Но опять же, я все еще учусь и много моих знаний о jsf из материала из блога @BalusC:), поэтому, если у этого подхода есть некоторые недостатки, пожалуйста, дайте мне знать.