0

When I select one group from dataTable, I want to display corresponding users in pickList. When I move some users within pickList, I want these new values to be saved in bean's object even before submitting the values, or before selection in dataTable is changed.

When I move a user from source pickList to target pickList (or vice versa), and then change selection in dataTable, the pickList source and target values stay the same as the were when they got populated.

User.java

package com.test.model;

public class User {
    private String userName;

    public User(String userName) {
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

Group.java

package com.test.model;

import java.util.List;

public class Group {
    private String groupName;
    private List<User> users;

    public Group(String groupName, List<User> users) {
        this.groupName = groupName;
        this.users = users;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

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

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

UserBean.java

package com.test.beans;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import com.test.model.Group;
import com.test.model.User;
import org.primefaces.model.DualListModel;

@ManagedBean
@ViewScoped
public class UserBean {
    private List<Group> groups = new ArrayList<>();
    private List<User> allUsers = new ArrayList<>();
    private Group selectedGroup;
    private DualListModel<User> users = new DualListModel<>();

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

    public Group getSelectedGroup() {
        return selectedGroup;
    }

    public void setSelectedGroup(Group selectedGroup) {
        this.selectedGroup = selectedGroup;
    }

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

    public void setUsers(DualListModel<User> users) {
        this.users = users;
    }

    @PostConstruct
    private void init()  {
        List<User> usersGroup1 = new ArrayList<>();
        usersGroup1.add(new User("User1"));
        usersGroup1.add(new User("User2"));

        List<User> usersGroup2 = new ArrayList<>();
        usersGroup2.add(new User("User3"));
        usersGroup2.add(new User("User4"));

        allUsers.addAll(usersGroup1);
        allUsers.addAll(usersGroup2);

        groups.add(new Group("Group1", usersGroup1));
        groups.add(new Group("Group2", usersGroup2));
    }

    public void onRowSelect() {
        // here I want to save the picklist source, but it is already reset
        List<User> storeUsers = users.getSource();
        fillPickList();
    }

    private void fillPickList() {
        List<User> assignedUsers = new ArrayList<>();
        List<User> availableUsers = new ArrayList<>();

        assignedUsers.addAll(selectedGroup.getUsers());
        availableUsers.addAll(allUsers);

        for (User user : assignedUsers) {
            if (availableUsers.contains(user))
                availableUsers.remove(user);
        }

        users.setSource(assignedUsers);
        users.setTarget(availableUsers);
    }
}

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">

<h:head>
    <link rel="shortcut icon" type="image/x-icon" href="#{resource['images/favicon.ico']}"/>
</h:head>

<h:body>
    <h:form>
        <p:dataTable value="#{userBean.groups}"
                     var="group"
                     selectionMode="single"
                     selection="#{userBean.selectedGroup}"
                     rowKey="#{group.groupName}">
            <p:column headerText="Groups">
                <h:outputText value="#{group.groupName}"/>
            </p:column>
            <p:ajax event="rowSelect"
                    listener="#{userBean.onRowSelect}"
                    update="@form"/>
        </p:dataTable>

        <p:pickList value="#{userBean.users}"
                    var="user"
                    itemLabel="#{user.userName}"
                    itemValue="#{user.userName}"/>
    </h:form>
</h:body>
</html>
Lopfest
  • 103
  • 10
  • Please run your application in development mode and see if you have any errors. And **always** create a [mcve] to help us determine where the problem **might** be. Now there are to many possible causes that are invisible. And 'guessing' or asking more details in multiple questions is too time consuming – Kukeltje Nov 24 '17 at 11:31
  • I don't understand the question. "I want these new values to be saved in bean's object even before submitting the values" - what? You don't want to send values to the server, but you want them to just appear on the server? – Vsevolod Golovanov Nov 25 '17 at 12:22
  • I want to be able to modify users from multiple groups and then save this changes all together – Lopfest Nov 26 '17 at 12:41

3 Answers3

1

I solved it by creating a Map<Group, Set<User>> and then working with this object and updating it on each item transfer via public void onTransfer(TransferEvent event) method.

But I still don't understand what are the getSource() and getTarget() methods for, when they are not updated dynamically.

Lopfest
  • 103
  • 10
  • You don't send the picklist data to the server when you change things. Use ajax for that too. Or **don't** process the picklist in thhttp://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes. Might make a difference – Kukeltje Nov 28 '17 at 09:47
  • http://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes – Jens Piegsa Jun 13 '19 at 13:43
1

I solved it like this.

My xhtml:

<p:pickList id="pickObjList" value="#{myMB.objectList}" var="valor" itemLabel="#{valor}" itemValue="#{valor}" >
                            <p:ajax event="transfer" listener="#{manutParamMB.onAlterarPickList}" update="pickValorList"/>
                            <f:facet name="sourceCaption">Remove</f:facet>
                            <f:facet name="targetCaption">Add</f:facet>
                        </p:pickList>

My ManagedBean:

public void onAlterarPickList(TransferEvent event) {
        for(Object item : event.getItems()) {
            
            if(event.isRemove()) {
                objectList.remove(item);
                log.info("Removed:"+item.toString());
            }
            else if(event.isAdd()) {
                objectList.add(item.toString());
                log.info("Added:"+item.toString());
            }
        }
    }
criscan
  • 91
  • 5
0

i simply surrounded my <pickList> element with a <form> and it worked. If doesn't work for you try to watch this youtube video, for this guy worked well. Here's my xhtml code:

<h:form>
    <p:pickList id="pickSkill"  value="#{curriculumBean.argomenti}" var="argomenti"
        itemLabel=" #{argomenti}" itemValue=" #{argomenti}"
        showCheckbox="true" showSourceControls="false"
        showTargetControls="false">
                <p:ajax event="transfer"
                    listener="#{curriculumBean.onTransfer}" update=":curriculumTab:list:growl" />
    </p:pickList>                                       
</h:form>
Scar H
  • 1
  • 1