Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f:selectOneMenu with parameter

Tags:

jsf

I have a set of groups (of users) and a table where I display these groups (and users). Each groups table header includes a f:selectOneMenu which allows to set a group-wide value. For the sake of this example, let it be a list of int values (0, 5, 10, 15, 20). Below the short version of things

Pojos:

public class User {
    private int    id;
    private String name;
    // .. getter, setter, equals, hashCode
}  

public class Group {
    private int    id;
    private String name;
    // .. getter, setter, equals, hashCode
}

Bean:

@ManagedBean(name = "oneSelectController")
@ViewScoped
public class OneSelectController implements Serializable {

    private List<User>                users;
    private List<Group>               groups;
    private List<Integer>             values;
    private Map<Group, List<User>>    usersToGroup;
    private Map<Group, List<Integer>> valuesToGroup;

    public OneSelectController() {

        log.info("New " + this.getClass().getSimpleName() + " ...");

        users = new ArrayList<>(4);
        users.add(new User(1, "User 1"));
        users.add(new User(2, "User 2"));
        users.add(new User(3, "User 3"));
        users.add(new User(4, "User 4"));

        groups = new ArrayList<>(5);
        groups.add(new Group(1, "Group 1"));
        groups.add(new Group(2, "Group 2"));
        groups.add(new Group(3, "Group 3"));
        groups.add(new Group(4, "Group 4"));
        groups.add(new Group(5, "Group 5"));

        values = Arrays.asList(0, 5, 10, 15, 20);

        usersToGroup = new HashMap<>();
        valuesToGroup = new HashMap<>();

        for (Group g : groups) {
            usersToGroup.put(g, users);
            valuesToGroup.put(g, values);
        }
    }

    public List<Group> getGroups() {
        return groups;
    }

    public List<User> getUsers() {
        return users;
    }

    public Integer getValueByGroup(Group group) {
        // return value for given group
    }

    public List<Integer> getValuesByGroup(Group group) {
        // return list of possible values
    }
}

XHTML:

<p:dataTable id="userTable"
             var="user"
             value="#{oneSelectController.users}">
    <p:column>
        <f:facet name="header">
            <div>User</div>
        </f:facet>
        <div>
            <h:outputText value="#{user.name}"/>
        </div>
    </p:column>
    <p:columns id="groups" value="#{oneSelectController.groups}" var="group">
        <f:facet name="header">
            <div>#{group.name}</div>
            <div>
                <h:selectOneMenu value="#{oneSelectController.getValueByGroup(group)}">
                    <f:selectItems value="#{oneSelectController.getValuesByGroup(group)}" />
                </h:selectOneMenu>
            </div>
        </f:facet>
    </p:columns>
</p:dataTable>

How do I set up a working setter for the h:selectOneMenu? Whatever I do, I end up with exceptions. The setter (somehow) must be capable to take the value selected, but also contain the information for which group the selection was made.

like image 321
John Smith Avatar asked Apr 01 '18 23:04

John Smith


1 Answers

getValueByGroup is not considered a getter by JSF, since you're using it with a parameter. I think your best here is to use a Map, properly implementing the hashCode() and equals() methods for Group class:

In your bean:

private Map<Group, Integer> selectedValueByGroup = new HashMap<>();
//Getter

In the view:

<h:selectOneMenu value="#{oneSelectController.selectedValueByGroup[group]}">
    <f:selectItems value="#{oneSelectController.getValuesByGroup(group)}" />
</h:selectOneMenu>

Also, unrelated to the concrete question and as @Kukeltje points out, you could use a Map structure to manage the values to show by group as well:

In your bean:

private Map<Group, List<Integer>> valuesByGroup = new HashMap<>();
//Getter

In the view:

<h:selectOneMenu value="#{oneSelectController.selectedValueByGroup[group]}">
    <f:selectItems value="#{oneSelectController.valuesByGroup[group]}" />
</h:selectOneMenu>

You might consider using a LinkedHashMap instead of a HashMap if the ordering is important to you too.

See also:

  • How to set a Map value in h:inputText
  • https://www.geeksforgeeks.org/internal-working-of-hashmap-java/
like image 147
Xtreme Biker Avatar answered Oct 24 '22 13:10

Xtreme Biker