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:), поэтому, если у этого подхода есть некоторые недостатки, пожалуйста, дайте мне знать.