How to update p:dataTable in p:rowExpansion - jsf

In my project, I have intertwined 2 datatables. I want to update second datatable when first datatable's rows expanded.
<h:form id="form2">
<p:dataTable var="modules" value="#{EVMView.allModules}" id="mydatatable">
<f:facet name="header">
Modules
</f:facet>
<p:column style="width:2rem">
<p:rowToggler/>
</p:column>
<p:column headerText="Module">
<h:outputText value="#{modules}"/>
</p:column>
<p:rowExpansion>
<div class="product">
<p:dataTable var="questions" value="#{EVMView.allQuestions}" id="mydatatable2">
<p:column style="width:2rem">
<p:rowToggler/>
</p:column>
<p:column headerText="Question">
<h:outputText value="#{questions}"/>
</p:column>
<p:rowExpansion>
</p:rowExpansion>
</p:dataTable>
</div>
</p:rowExpansion>
</p:dataTable>
</h:form>
When I expand mydatatable's row, I don't see the values in mydatatable2.
So I know I have to update mydatatable2 too, but I couldn't find how to do it.
EDİT
According to #Jasper's answer, I added ViewScoped in my bean and I added this ajax in my first datatable.
<p:ajax event="rowToggle" listener="#{EVMView.updateTable2()}"/>
My bean is like this
package com.utc.pw.ui;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.PrimeFaces;
import com.utc.pw.domain.EVMOptions;
import com.utc.pw.domain.EVMQuestions;
import com.utc.pw.domain.SalesOrder;
import com.utc.pw.service.EVMService;
import com.utc.pw.service.PublicService;
#ManagedBean(name="EVMView")
#ViewScoped
public class EVMView {
#EJB
private PublicService publicService;
#EJB
private EVMService evmService;
private EVMQuestions evmQuestions=new EVMQuestions();
private String strSO;
private List<SalesOrder> salesOrders;
private List<String> allModules;
private List<EVMQuestions> allQuestions;
private String selectedOption;
private List<EVMOptions> optionList;
private String answer;
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public List<EVMOptions> getOptionList() {
return optionList;
}
public void setOptionList(List<EVMOptions> optionList) {
this.optionList = optionList;
}
public String getSelectedOption() {
return selectedOption;
}
public void setSelectedOption(String selectedOption) {
this.selectedOption = selectedOption;
}
public List<EVMQuestions> getAllQuestions() {
return allQuestions;
}
public void setAllQuestions(List<EVMQuestions> allQuestions) {
this.allQuestions = allQuestions;
}
public PublicService getPublicService() {
return publicService;
}
public void setPublicService(PublicService publicService) {
this.publicService = publicService;
}
public EVMService getEvmService() {
return evmService;
}
public void setEvmService(EVMService evmService) {
this.evmService = evmService;
}
public EVMQuestions getEvmQuestions() {
return evmQuestions;
}
public void setEvmQuestions(EVMQuestions evmQuestions) {
this.evmQuestions = evmQuestions;
}
public String getStrSO() {
return strSO;
}
public void setStrSO(String strSO) {
this.strSO = strSO;
}
public List<SalesOrder> getSalesOrders() {
return salesOrders;
}
public void setSalesOrders(List<SalesOrder> salesOrders) {
this.salesOrders = salesOrders;
}
public List<String> getAllModules() {
return allModules;
}
public void setAllModules(List<String> allModules) {
this.allModules = allModules;
}
#PostConstruct
public void init() {
this.salesOrders = publicService.getAllSalesOrders();
}
public void loadModules()
{
this.allModules=evmService.getAllModules(strSO);
this.allQuestions=evmService.getAllQuestions(strSO);
PrimeFaces.current().ajax().update("form2:mydatatable");
//PrimeFaces.current().ajax().update("form3:mydatatable2");
}
public void updateTable2()
{
PrimeFaces.current().ajax().update(":mydatatable2");
}
public List<EVMOptions> options(String module,int questionID)
{
this.optionList=evmService.getOptions(strSO, module, questionID);
return optionList;
}
}

You don't need to update the table in the p:rowExpansion when it is expanded as it is lazy loaded by default. What you do need to do is make sure that you child p:dataTable value="#{...}" is set correctly. To do so, add a listener on the outer p:dataTable and set the model based on the expanded row. You will need to use the rowToggle event, which takes a ToggleEvent as the parameter.
As your table has multiple rows of modules, you should have model in your bean which can contain multiple modules, like a Map with the module ID as the key and the questions as the value. Add module entries in your rowToggle handler.
Also make sure your bean is at least ViewScoped.
See also:
https://primefaces.github.io/primefaces/10_0_0/#/components/ajaxbehavior
How to choose the right bean scope?

Related

Passing additional Objects to commandLink

I want to use the same View for different states of a bean. Therefore I need to Inject/pass/whatever get the current bean I want to modify, but I always get null.
I already tried it with , with #Inject, and the other solutions given in How can I pass selected row to commandLink inside dataTable or ui:repeat?
The View:
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import org.primefaces.PrimeFaces;
import de.auticon.beans.Mitarbeiter;
import de.auticon.beans.Skill;
#Named(value = "skillView")
#ViewScoped
public class SkillView implements Serializable {
private static final long serialVersionUID = -3256509521249071048L;
private Mitarbeiter employee;
private Skill skill = new Skill();
private List<String> expertises = new ArrayList<String>();
#PostConstruct
public void init() {
List<Expertise_String> expertiseObjects = Queries.findAllExpertises();
for (Expertise_String singleExpertise : expertiseObjects) {
expertises.add(singleExpertise.getExpertise() + " - " + singleExpertise.getFullNameString());
}
}
//Here employee is null, but I need the new/existing employee
public void addSkill() {
employee.getSkills().add(skill);
PrimeFaces.current().dialog().closeDynamic(null);
}
public void closeDialog() {
PrimeFaces.current().dialog().closeDynamic(null);
}
public Skill getSkill() {
return skill;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
public Mitarbeiter getEmployee() {
return employee;
}
public void setEmployee(Mitarbeiter employee) {
this.employee = employee;
}
}
XHTML from which it is called for existing employees:
<h:form id="form">
<p:panelGrid columns="2" styleClass="ui-noborder">
<p:menu toggleable="true">
<p:submenu label="Verwaltung">
<p:menuitem>
<p:commandButton value="Mitarbeiter anlegen" action="#{adminView.addNewEmployee}" icon="pi pi-users"
process="#this :form:skillsDialog">
<p:ajax event="dialogReturn" listener="#{mitarbeiterView.update}" update=":form, :form:table"/>
</p:commandButton>
</p:menuitem>
</p:submenu>
</p:menu>
<p:dataTable id="table" var="row" value="#{mitarbeiterView.mitarbeiter}" liveResize="true" resizableColumns="true">
<p:column headerText="Skillset">
<p:commandLink update=":form:skillsDialog, :form:skillsDetails" oncomplete="PF('skillsDialog').show()" title="Detail"
styleClass="ui-icon pi pi-search">
<f:setPropertyActionListener value="#{row}" target="#{mitarbeiterView.selectedEmployee}" />
</p:commandLink>
<p:commandLink action="#{adminView.openNewSkillDialog(row)}" title="add" styleClass="ui-icon pi pi-plus">
<!-- <f:setPropertyActionListener value="#{row}" target="#{skillView.employee}" /> -->
</p:commandLink>
</p:column>
</p:dataTable>
</p:panelGrid>
<p:dialog id="skillsDialog" header="Skillsheet von #{mitarbeiterView.selectedEmployee.vorname} #{mitarbeiterView.selectedEmployee.name}"
showEffect="fade" widgetVar="skillsDialog" modal="true" resizable="true">
<p:outputPanel id="skillsDetails">
<p:dataTable var="skillRow" value="#{mitarbeiterView.selectedEmployee.skills}">
<p:column headerText="Skill">
<h:outputText value="#{skillRow.name}" />
</p:column>
<p:column headerText="Ausprägung">
<h:outputText value="#{skillRow.expertise} - #{skillRow.expertiseString.fullName}" />
</p:column>
<p:column headerText="Beschreibung">
<h:outputText value="#{skillRow.description}" />
</p:column>
</p:dataTable>
</p:outputPanel>
</p:dialog>
</h:form>
Second XHTML, for new employees:
<h:form id="newForm">
<h3>Skillsheet</h3>
<p:panelGrid id="skillPanel" columns="2" cellpadding="5" styleClass="ui-noborder">
<p:column style="width:50px">
<p:commandButton id="openAddSkill" process="#this" action="#{adminView.openNewSkillDialog}"
title="Neuer Skill" icon="pi pi-plus">
<!-- <f:setPropertyActionListener target="#{skillView.employee}" value="#{newEmployeeView.newEmployee}"/> -->
<p:ajax event="dialogReturn" update=":newForm :newForm:skillPanel"/>
</p:commandButton>
</p:column>
</p:panelGrid>
<p:commandButton value="Hinzufügen" id="addSkill" icon="pi pi-plus" action="#{skillView.addSkill()}"/>
</h:form>
AdminView.java:
#Named(value = "adminView")
#ViewScoped
public class AdminView implements Serializable {
private static final long serialVersionUID = 5252224062484767900L;
#Inject
private SkillView skillView;
public void addNewEmployee() {
Map<String, Object> options = new HashMap<String, Object>();
options.put("id", "newEmployeeDialogID");
options.put("widgetVar", "newEmployeeDialogVar");
options.put("resizable", false);
options.put("modal", false);
PrimeFaces.current().dialog().openDynamic("/dialogs/newEmployee", options, null);
}
public void openNewSkillDialog(Mitarbeiter employee) {
Map<String, Object> options = new HashMap<String, Object>();
options.put("resizable", true);
options.put("modal", false);
options.put("contentWidth", 420);
PrimeFaces.current().dialog().openDynamic("/dialogs/skill", options, null);
skillView.setEmployee(employee);
}
}
Skill.java:
public class Skill {
#NotNull(message = "Skill fehlt")
private String name;
#NotNull(message = "Bitte Ausprägung angeben")
private short expertise;
private String description;
private String expertiseFullname;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public short getExpertise() {
return expertise;
}
public void setExpertise(short expertise) {
this.expertise = expertise;
}
public String getExpertiseFullname() {
return expertiseFullname;
}
public void setExpertiseFullname(String expertiseFullname) {
this.expertiseFullname = expertiseFullname;
}
public void setExpertise(String fullName) {
try {
this.expertise = Short.valueOf(fullName.substring(0, fullName.indexOf(" - ")));
} catch (Exception e) {
this.expertise = 0;
}
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Mitarbeiter.java:
public class Mitarbeiter {
private int id;
#NotNull(message = "Nachname fehlt")
private String name;
#NotNull(message = "Vorname fehlt")
private String vorname;
private Date entryDate;
private List<Skill> skills = new ArrayList<Skill>();
private int expertise;
public Mitarbeiter() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVorname() {
return vorname;
}
public void setVorname(String vorname) {
this.vorname = vorname;
}
public List<Skill> getSkills() {
return skills;
}
public void setSkills(List<Skill> skills) {
this.skills = skills;
}
public int getExpertise() {
return expertise;
}
public void setExpertise(int expertise) {
this.expertise = expertise;
}
MitarbeiterView.java:
#Named(value = "mitarbeiterView")
#ViewScoped
public class MitarbeiterView implements Serializable {
private static final long serialVersionUID = 7924178697538784022L;
#Inject
MitarbeiterService mitarbeiterService;
private List<Mitarbeiter> mitarbeiter;
private Mitarbeiter selectedEmployee;
#PostConstruct
public void init() {
SessionConfig.initSession();
new Commons();
updateMitarbeiter();
}
private void updateMitarbeiter() {
mitarbeiter = new ArrayList<Mitarbeiter>();
List<EmployeeDTO> dtos = Queries.findAllEmployees();
for (EmployeeDTO employeeDTO : dtos) {
mitarbeiter.add(mitarbeiterService.convertToMitarbeiter(employeeDTO));
}
}
public void update() {
updateMitarbeiter();
PrimeFaces.current().ajax().update("form:table");
}
public List<Mitarbeiter> getMitarbeiter() {
return mitarbeiter;
}
public void setMitarbeiter(List<Mitarbeiter> mitarbeiter) {
this.mitarbeiter = mitarbeiter;
}
public void setSelectedEmployee(Mitarbeiter selectedEmployee) {
this.selectedEmployee = selectedEmployee;
}
public Mitarbeiter getSelectedEmployee() {
return selectedEmployee;
}
NewEmployeeView.java:
#Named(value = "newEmployeeView")
#ViewScoped
public class NewEmployeeView implements Serializable {
private static final long serialVersionUID = 789108010781037452L;
#ManagedProperty(value = "#{mitarbeiter}")
private Mitarbeiter newEmployee = new Mitarbeiter();
#PostConstruct
public void init() {
}
public Mitarbeiter getNewEmployee() {
return newEmployee;
}
public void setNewEmployee(Mitarbeiter mitarbeiter) {
this.newEmployee = mitarbeiter;
}
Calling adSkill() from the first XHTML should have the selected employee from the Datatable. In the second case, it should have a freshly created, "empty" employee, which I already provide.
I think that major cause of your problems is that skillView bean is #RequestScoped meaning that it is being constructed and destroyed on each request and thus your employee is being reinitialized/reset to null every time. Check out this accepted answer for details.
Hints that might lead you to solution:
put debug lines in at least init() and setEmployee(..) methods of skillView and observe behaviour,
change scope of skillView to #ViewScoped which will preserve employee object across multiple Ajax requests

Display List<List> in <p:dataTable><p:columns>

I am trying to display below list of list of object in datatable. But nothing is showing up. Help is very much appreciated!
public class TimrsDisplayBean {
private static final long serialVersionUID = 1L;
private String teamName = "";
private String teamType = "";
private boolean reported;
private boolean noProd;
private boolean missing;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public String getTeamType() {
return teamType;
}
public void setTeamType(String teamType) {
this.teamType = teamType;
}
public boolean getReported() {
return reported;
}
public void setReported(boolean reported) {
this.reported = reported;
}
public boolean getNoProd() {
return noProd;
}
public void setNoProd(boolean noProd) {
this.noProd = noProd;
}
public boolean getMissing() {
return missing;
}
public void setMissing(boolean missing) {
this.missing = missing;
}
}
XHTML FILE
<p:dataTable value="#{dashboardMBean.timrsDisplayDataList}" var="var" rowIndexVar="row"
styleClass="large-card-datatable alternatingRowTable no-border nowrap">
<f:facet name="header">
<span class="updateDate"> </span>
</f:facet>
<p:column headerText="Type" value=" #{dashboardMBean.timrsDisplayDataList[0]}" columnIndexVar="i">
#{var[i].teamType}
</p:column>
<p:column headerText="Type" value=" #{dashboardMBean.timrsDisplayDataList[0]}" columnIndexVar="i">
#{var[i].teamName}
</p:column>
Please support full code parts if possible. Your datatable tag doesn't even finish.
Beside that, it seems like you've done too much work. Did you try to calculate the row indices by yourself? Not needed. The basic column definiton is more comfortable. Use your defined variable var to name each element/row as shown in the Primefaces showcase:
http://www.primefaces.org/showcase/ui/data/datatable/basic.xhtml
In your case, it will be something like
<p:column headerText="Type">
<h:outputText value="#{var.teamType}"/>
</p:column>
Plus, as Jasper De Vries said correctly, there is no attribute called columnIndexVar. Remove it to prevent strange behaviour.
If this is not enough, you need to share some more code of your ManagedBean. Not sure if your posted java class represent your Bean, but if so, you need to declare it as a ManagedBean like
#ManagedBean(name = "timrsDisplayBean)
#SessionScoped
public class TimrsDisplayBean {
I hope this helps!

Password field <p:password> Value Won't Re-Appear In Form After Saved And Selecting That Row From Data Table [duplicate]

This question already has an answer here:
p:password doesn't redisplay prefilled model value
(1 answer)
Closed 6 years ago.
So, I am taking in a password value from a form which is being saved to an object. The objects are saved to a data table. I have the functionality to allow a user to select a row from the data table, and the values for that object will be populated back into the form. Unfortunately, all values will populate except the password field. If I alter the password field to become an inputText, the value will be shown after selecting the row from the data table. Below is the code. Thanks.
HTML
Customer Registration
<p:panelGrid columns="2">
<p:commandButton value="Submit" image="ui-icon-check" ajax="false" actionListener="#{createPerson.createPerson()}"/>
</p:panelGrid><br/>
<p:panel id="table">
<p:dataTable id="dataTable" editable="false" var="person" paginator="true" rows="5" selectionMode="single"
value="#{createPerson.dataModel}" rowKey="#{person.id}">
<f:facet name="header">
Record
</f:facet>
<p:ajax listener="#{createPerson.processUserSelection}" event="rowSelect" update=":createPersonForm"/>
<p:ajax listener="#{createPerson.processUserUnselection}" event="rowUnselect" update=":createPersonForm"/>
<p:column sortBy="id" headerText="ID">
<h:outputText value="#{person.id}" />
</p:column>
<p:column sortBy="ssn" headerText="SSN">
<h:outputText value="#{person.ssn}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
</h:body>
</html>
Person
public class Person {
private String ssn;
private String id;
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Create Person
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
#ManagedBean(name = "createPerson")
#SessionScoped
public class CreatePerson {
private Person person;
List<Person> personList = new ArrayList<>();
private PersonDataModel dataModel;
private static int id = 0;
public CreatePerson() {
person = new Person();
dataModel = new PersonDataModel(personList);
}
public String getSsn() {
return person.getSsn();
}
public void setSsn(String ssn) {
person.setSsn(ssn);
}
public void createPerson(){
System.out.println(" Submit Button clicked..");
System.out.println(" SSN: " + person.getSsn());
if (person.getId() == null || person.getId().equalsIgnoreCase("-1")) {
//New Person
person.setId("" + (id++));
personList.add(person);
person = new Person();
person.setId("-1");
}
else {
}
}
public void processUserSelection(SelectEvent evt) {
System.out.println(" Row selected from the Data Table .");
this.person = (Person) evt.getObject();
}
public void processUserUnselection(UnselectEvent evt) {
System.out.println(" Row unselected from the Data Table .");
this.person = new Person();
this.person.setId("-1");
}
public PersonDataModel getDataModel(){
return this.dataModel;
}
}
Data Table Class
import java.util.List;
import javax.faces.model.ListDataModel;
import org.primefaces.model.SelectableDataModel;
public class PersonDataModel extends ListDataModel<Person> implements SelectableDataModel<Person>{
public PersonDataModel() {
}
public PersonDataModel(List<Person> data) {
super(data);
}
#Override
public Person getRowData(String rowKey){
System.out.println("Key = " + rowKey);
List<Person> persons = (List<Person>) getWrappedData();
for (Person person : persons) {
if(person.getId().equals(rowKey)){
return person;
}
}
System.out.println("Valid Person not found");
return null;
}
#Override
public Object getRowKey(Person person){
return person.getId();
}
}
Its a high risk to display password ,if you will look into Primeface <p:password /> its a extension of JSF <h:inputSecret /> .
It have a attribute called redisplay by default its value should be false
Boolean flag indicating whether or not a previously entered password
should be rendered in form. Default is false.
Now add this attribute(redisplay="true") in your component.
For more information you can check Tag inputSecret
Render the clientId of the component as the value of the "name"
attribute. Render the current value of the component as the value of
the "value" attribute, if and only if the "redisplay" component
attribute is the string "true". If the "styleClass" attribute is
specified, render its value as the value of the "class" attribute.

RichFaces dynamic TabPanel

How to implement a simple add/remove dynamic <rich:tabPanel>?
(I've seen people asking this around so I thought postin a Q&A of a simple implementation)
The implementation has 3 custom classes:
Content: contains the values to be displayed in a tab;
ItemTab: contais an UITab object and a Content object;
MyTabs: EJB managed bean that provides access to the tabs and adding/removal methods.
The code is:
Content:
public class Content {
String name;
String job;
String dept;
public Content() {
name = "John Doe";
job = "None";
dept = "None";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}
TabItem:
public class TabItem {
UITab component;
Content content;
public TabItem() {
component = new UITab();
content = new Content();
}
public UITab getComponent() {
return component;
}
public void setComponent(UITab tab) {
this.component = tab;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
}
MyTabs:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class MyTabs implements Serializable {
private List<TabItem> tabs;
public MyTabs() {
tabs = new ArrayList<TabItem>();
}
#PostConstruct
private void init() {
createTab();
createTab();
createTab();
}
public void createTab() {
TabItem tab = new TabItem();
tab.getComponent().setId("Tab" + (tabs.size()+1));
tab.getComponent().setHeader("Tab " + (tabs.size()+1));
tab.getContent().setName("John Doe " + (tabs.size()+1));
tab.getContent().setJob("Salesman " + (tabs.size()+1));
tab.getContent().setDept("Sales " + (tabs.size()+1));
tabs.add(tab);
}
public void removeTab(TabItem tab) {
tabs.remove(tab);
}
public List<TabItem> getTabs() {
return tabs;
}
public void setTabs(List<TabItem> tabs) {
this.tabs = tabs;
}
}
tabview.xhtml:
<h:commandLink value="Add Tab"
actionListener="#{myTabs.createTab()}"/>
<rich:tabPanel switchType="client">
<c:forEach items="#{myTabs.tabs}" var="tab">
<rich:tab value="#{tab.component}">
<f:facet name="header">
<h:outputLabel value="#{tab.component.header}"/>
<h:commandLink value=" X" actionListener="#{myTabs.removeTab(tab)}"/>
</f:facet>
<h:panelGrid columns="2">
<h:outputLabel value="Name: "/>
<h:outputLabel value="#{tab.content.name}"/>
<h:outputLabel value="Dept: "/>
<h:outputLabel value="#{tab.content.dept}"/>
<h:outputLabel value="Job: "/>
<h:outputLabel value="#{tab.content.job}"/>
</h:panelGrid>
</rich:tab>
</c:forEach>
</rich:tabPanel>

DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.

I'm trying to create a DataTable with Multiple Row Selection but i'm getting an error here's the link of the tutorial http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf :
Here's my xhtml:
<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}"
var="userObj"
selection="#
{projectAdminisrationMB.selectedUsers}"
selectionMode="multiple" rowIndexVar="rowIndex"binding="#{table2}">
<p:column id="column3">
<f:facet name="header">
<h:outputText value=" user "></h:outputText>
</f:facet>
<h:outputText value="#{userObj.name}"/>
/
<h:outputText value="#{userObj.lastName}"></h:outputText>
<h:outputText value="#{userObj.firstName}"></h:outputText>
</p:column>
<f:facet name="footer">
<p:commandButton id="addProjectUser" value=" Add " onclick="dlg1.show()" />
<p:commandButton id="deleteProjectUser" value=" Delete " />
</f:facet>
</p:dataTable>
Managed Bean :
#ManagedBean
#SessionScoped
public class ProjectAdminisrationMB implements Serializable {
private static final long serialVersionUID = 1L;
private String projectName;
private List <User> projectUsersList;
private List<User> projectNoUsersList;
private List<User> selectedUsers;
private String projectAdmin;
public ProjectAdminisrationMB() {
super();
AdministrationProjectFinal administrationProjectFinal =new
AdministrationProjectFinal();
this.projectUsersList=administrationProjectFinal.getUserList();
this.projectNoUsersList=administrationProjectFinal.getNotUserList();
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public List<User> getProjectUsersList() {
return projectUsersList;
}
public void setProjectUsersList(List<User> projectUsersList) {
this.projectUsersList = projectUsersList;
}
public String getProjectAdmin() {
return projectAdmin;
}
public void setProjectAdmin(String projectAdmin) {
this.projectAdmin = projectAdmin;
}
public List<User> getProjectNoUsersList() {
return projectNoUsersList;
}
public void setProjectNoUsersList(List<User> projectNoUsersList) {
this.projectNoUsersList = projectNoUsersList;
}
public List<User> getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(List<User> selectedUsers) {
this.selectedUsers = selectedUsers;
}
}
i'm getting this error:
javax.faces.FacesException: DataModel must implement
org.primefaces.model.SelectableDataModel when selection is enabled.....
just add this attribute rowKey to the datatable tag :
<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}"
var="userObj"
rowKey="#{userObj.name}"selection="#{projectAdminisrationMB.selectedUsers}"
selectionMode="multiple" rowIndexVar="rowIndex"
binding="#{table2}">
You can get this error if you try to add a new item to the underlying list and forget to assign a value to that new item's rowKey.
Alternatively to rowKey you can wrap your data in a custom model which really implements org.primefaces.model.SelectableDataModel. This is helpful if
all of your your classes have the same kind of #Id (e.g. a long) and can implement the same interface (e.g. EjbWithId)
you want to add additional functionalities to your data which are not domain specific and don't belong e.g. User.
The interface may be something like this:
public interface EjbWithId
{
public long getId();
public void setId(long id);
}
Then a generic implementation of SelectableDataModel for all your classes can be used:
public class PrimefacesEjbIdDataModel <T extends EjbWithId>
extends ListDataModel<T> implements SelectableDataModel<T>
{
public PrimefacesEjbIdDataModel(List<T> data)
{
super(data);
}
#Override public T getRowData(String rowKey)
{
List<T> list = (List<T>) getWrappedData();
for(T ejb : list)
{
if(ejb.getId()==(new Integer(rowKey))){return ejb;}
}
return null;
}
#Override public Object getRowKey(T item) {return item.getId();}
}
In your #ManagedBean:
private PrimefacesEjbIdDataModel<User> dmUser; //+getter
dmUser = new PrimefacesEjbIdDataModel<User>(administrationProjectFinal.getUserList());
first check whether you've added
rowKey="#{userObj.id}"
then you need to have the data table List set in filteredValue attribute of your data table in xhtml, instead of value.

Resources