tags:

views:

68

answers:

1

Hello.. I'm trying to create a jsf datatable with select one menu and to fill it from database but can't get it work here is my JSF code:

  <ice:dataTable id="dataTable1" value="#{Page1.users}" var="users">
                        <ice:column id="column2">

                           <ice:outputText id="userID" value="users.userId"/>
                            <f:facet name="header">
                                <ice:outputText id="outputText1" value="Table_Column1"/>
                            </f:facet>

                        </ice:column>

                        <ice:column id="column2">


                            <f:facet name="header">
                                <ice:outputText id="outputText4" value="Table_Column2"/>
                            </f:facet>
                            <ice:selectOneMenu id="users" value="#{Page1.selectedUser}" >
                            <f:selectItems value="#{users.screenName}"/>

                            </ice:selectOneMenu>
                        </ice:column>

                    </ice:dataTable>

Page1 code:

 private ArrayList<UserTable> users=new ArrayList<UserTable>();

    public ArrayList<UserTable> getUsers() {

        if(users==null){
            UserTable u1=new UserTable(1);
            users.add(u1);
            u1=new UserTable(2);
            users.add(u1);

        }
        return users;
    }
    private String selectedUser;

    public String getSelectedUser() {
        return selectedUser;
    }

    public void setSelectedUser(String selectedUser) {
        this.selectedUser = selectedUser;
    }

and Finally userTable code:

public class UserTable {
    private long userId;
    private Option[] screenName;

    public UserTable(long userId) {
        this.userId = userId;
    }

    public Option[] getScreenName() {
        if(screenName==null){
        buildScreenNameOptions();
        }
        return screenName;
    }

    public void setScreenName(Option[] screenName) {
        this.screenName = screenName;
    }


    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    private void buildScreenNameOptions() {
    List<String> screenNameList = null;
    try{
        Session session = NewHibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery("Select screenName from User");
        screenNameList = (List<String>) q.list();

    } catch(Exception e) {
        e.printStackTrace();
    }

    screenName = new Option[screenNameList.size()];
    int i=0;
    for(String name : screenNameList) {
        Option opt = new Option(name);
       screenName[i++] = opt;
    }
}


}

So what's going wrong?

Thanks

A: 

Here,

<ice:selectOneMenu id="users" value="#{Page1.selectedUser}" >

you're binding the input value with a single managed bean property instead of the property of the iterated row object #{users}. So, when the table has multiple rows, then the single managed bean property will be overwritten everytime until the last row. This property ends up to be always the value of the last row. You need to bind the input value to the iterated row object instead.

And here,

<f:selectItems value="#{users.screenName}" />

The f:selectItems should be bound to a List<SelectItem> or a SelectItem[] or a Map<Object, Object>. I am not sure what Option[] should represent, but that look like ICEFaces specific. Since you didn't describe the problem (you just said "it's not working" like in enduser's perspective, not in developer's perspective), I just try to be on the safe side and suggest you to use List<SelectItem> for this.

Here's a basic kickoff example how the one and other should look like. I'm using self-explaining variable names here so that the code is more clear and self-documenting:

<h:dataTable value="#{bean.users}" var="user">
    <h:column>
        <h:selectOneMenu value="#{user.selectedScreenName}">
            <f:selectItems value="#{user.availableScreenNames}" />
        </h:selectOneMenu>
    </h:column>
</h:dataTable>

with

public class Bean {
    private List<User> users;
    // ...
}

and

public class User {
    private String selectedScreenName;
    private List<SelectItem> availableScreenNames;

    public User() {
        availableScreenNames = new ArrayList<SelectItem>();
        for (String availableScreenName: session.createQuery(SQL).list()) {
            availableScreenNames.add(new SelectItem(availableScreenName));
        }
    }

    // ...
}

That said, I am not sure how the "booleancheckbox" (as you put in your title) is related to this problem. In the future, try to be a bit more descriptive in the question. Telling "it doesn't work" doesn't give us much to work with, it'll be only guessing based on the given code.

BalusC
Thanks but If I have two selectOneMenu in each row where the second value depened on the first one how could I manage there values?
Feras