Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

selectonemenu inside table in jsf2

I have a table with 2 selectOneMenu components.

I would like that once a record was chosen in the first selectOneMenu component it will update the other selectOneMenu with Ajax in the same row.

My table:

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

In the bean I have:

List<SelectItem> myList,mySecondList;

public void refershNames(AjaxBehaviorEvent event){
    //how can I retrieve the selected item and update the relevant record?
}

How can I do it with Ajax? I am using JSF2

like image 658
Dejell Avatar asked Feb 24 '11 16:02

Dejell


2 Answers

Wrap the datatable value in DataModel<E> so that you can obtain the myInfo object in question by DataModel#getRowData(). So,

DataModel<MyInfo> myInfoModel; // +getter

@PostConstruct
public void init() {
    myInfo = myInfoDAO.list();
    myInfoModel = new ListDataModel<MyInfo>(myInfo);
}

with

<h:dataTable value="#{myBean.myInfoModel}" var="myInfo">

and

public void refreshNames(AjaxBehaviorEvent event){
    MyInfo myInfo = myInfoModel.getRowData();
    // Get code and update secondCode.
}

Update as per the comments, here is the testcase I created after you told that it didn't work. It worked for me with Mojarra 2.0.3 on both Tomcat 7.0.5 and 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>

This testcase proves that whenever you change a dropdown value in the 1st column, then the dropdown value in the 2nd column in the same row will be reflected to retrieve the same value.

like image 158
BalusC Avatar answered Oct 23 '22 12:10

BalusC


i had the same issue and after a lot of trial and error this worked for me

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

public void predefinedMessageChangeListener(ValueChangeEvent e)
{

        getPredefinedMessageOptions(Integer.parseInt(e.getNewValue().toString()));


}

This is simple and works perfectly for me , as the message that i choose in the first column updates the options in the second column and its done through ajax. But then again, i m still learning and alot of my knowledge of jsf is from material from @BalusC blog :), so if this approach has some flaws, please lemme know.

like image 1
Khizar Avatar answered Oct 23 '22 11:10

Khizar