On Primefaces datatable lazy loading complete update backing bean - primefaces

I want to update backing bean after the primefaces datatable lazy loading is complete. I see that the API has a onSuccess & onComplete method for calling clientside code. But I would like to update backing bean based on the default selection. I have registered the "page" event with my datatable
<p:ajax event="page" update="" onstart="PF('loadingDialog').show()" onsuccess="PF('loadingDialog').hide()" listener=""/>
I could have used the listener but the problem is listener is invoked even before the server side loading method is complete.

RemoteCommand provides a simple way to execute backing bean methods with javascript.
The example is shown below.
xhtml
<h:form id="form">
<p:remoteCommand name="rc" update="msgs"
actionListener="#{remoteCommandView.execute('Wittakarn')}" />
<p:growl id="msgs" showDetail="true" />
<p:dataTable var="car" value="#{dtLazyView.lazyModel}"
paginator="true" rows="10"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink}
{PreviousPageLink}
{CurrentPageReport}
{NextPageLink}
{LastPageLink}"
rowsPerPageTemplate="5,10,15"
selectionMode="single"
selection="#{dtLazyView.selectedCar}"
id="carTable"
lazy="true">
<p:ajax event="rowSelect"
listener="#{dtLazyView.onRowSelect}"
update=":form:carDetail"
oncomplete="PF('carDialog').show()" />
<p:ajax event="page"
update=":form:carDetail"
oncomplete="rc()" />
<p:column headerText="Id"
sortBy="#{car.id}"
filterBy="#{car.id}">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year"
sortBy="#{car.year}"
filterBy="#{car.year}">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand"
sortBy="#{car.brand}"
filterBy="#{car.brand}">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color"
sortBy="#{car.color}"
filterBy="#{car.color}">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
<p:dialog header="Car Detail"
widgetVar="carDialog"
modal="true" showEffect="fade"
hideEffect="fade"
resizable="false">
<p:outputPanel id="carDetail"
style="text-align:center;">
<p:panelGrid columns="2"
rendered="#{not empty dtLazyView.selectedCar}"
columnClasses="label,value">
<f:facet name="header">
<p:graphicImage
name="demo/images/car/#{dtLazyView.selectedCar.brand}-big.gif"/>
</f:facet>
<h:outputText value="Id:" />
<h:outputText value="#{dtLazyView.selectedCar.id}" />
<h:outputText value="Year" />
<h:outputText value="#{dtLazyView.selectedCar.year}" />
<h:outputText value="Color:" />
<h:outputText value="#{dtLazyView.selectedCar.color}"
style="color:#{dtLazyView.selectedCar.color}"/>
<h:outputText value="Price:" />
<h:outputText value="#{dtLazyView.selectedCar.price}">
<f:convertNumber type="currency" currencySymbol="$" />
</h:outputText>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
managedbean
#ManagedBean
public class RemoteCommandView {
public void execute() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", "Using RemoteCommand."));
}
public void execute(String detail) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, detail, "Using RemoteCommand."));
}
}
#ManagedBean(name="dtLazyView")
#ViewScoped
public class LazyView implements Serializable {
private LazyDataModel<Car> lazyModel;
private Car selectedCar;
#ManagedProperty("#{carService}")
private CarService service;
#PostConstruct
public void init() {
lazyModel = new LazyCarDataModel(service.createCars(200));
}
public LazyDataModel<Car> getLazyModel() {
return lazyModel;
}
public Car getSelectedCar() {
return selectedCar;
}
public void setSelectedCar(Car selectedCar) {
this.selectedCar = selectedCar;
}
public void setService(CarService service) {
this.service = service;
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("Car Selected", ((Car) event.getObject()).getId());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
model
public class Car implements Serializable {
public String id;
public String brand;
public int year;
public String color;
public int price;
public boolean sold;
public Car() {}
public Car(String id, String brand, int year, String color) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
}
public Car(String id, String brand, int year, String color, int price, boolean sold) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
this.price = price;
this.sold = sold;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public boolean isSold() {
return sold;
}
public void setSold(boolean sold) {
this.sold = sold;
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Car other = (Car) obj;
if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
return false;
}
return true;
}
}
carService
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.showcase.domain.Car;
#ManagedBean(name = "carService")
#ApplicationScoped
public class CarService {
private final static String[] colors;
private final static String[] brands;
static {
colors = new String[10];
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
brands = new String[10];
brands[0] = "BMW";
brands[1] = "Mercedes";
brands[2] = "Volvo";
brands[3] = "Audi";
brands[4] = "Renault";
brands[5] = "Fiat";
brands[6] = "Volkswagen";
brands[7] = "Honda";
brands[8] = "Jaguar";
brands[9] = "Ford";
}
public List<Car> createCars(int size) {
List<Car> list = new ArrayList<Car>();
for(int i = 0 ; i < size ; i++) {
list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState()));
}
return list;
}
private String getRandomId() {
return UUID.randomUUID().toString().substring(0, 8);
}
private int getRandomYear() {
return (int) (Math.random() * 50 + 1960);
}
private String getRandomColor() {
return colors[(int) (Math.random() * 10)];
}
private String getRandomBrand() {
return brands[(int) (Math.random() * 10)];
}
private int getRandomPrice() {
return (int) (Math.random() * 100000);
}
private boolean getRandomSoldState() {
return (Math.random() > 0.5) ? true: false;
}
public List<String> getColors() {
return Arrays.asList(colors);
}
public List<String> getBrands() {
return Arrays.asList(brands);
}
}
You can see more detail: RemoteCommand

Since I prefer using vanilla JSF, I would do the following
put this above your table
<h:commandButton id="call-me-after-page"
style="display:none;" action="#{myBean.myAction}">
<f:ajax execute="#form" render="#form"></f:ajax>
</h:commandButton>
and set the oncomplete like this:
<p:ajax event="page" oncomplete="$('#call-me-after-page').click();"></p:ajax>

Related

datatable with lazyloading and rowexpansion gives wrong object when opening expansion

I'm using a normal datatable with lazyloading and rowexpansion with a nested table and I have problems by opening the rowexpansion after lazyloading. ScrollRows is setted to 150.
<ui:composition template="/ressources/basic.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<ui:define name="title">#{label['template.tab1']}</ui:define>
<ui:define name="content">
<h:form id="crateTbl">
<p:dataTable rowExpandMode="single" id="cTbl" var="crate" value="#{cratesView.lazyModel}" selectionMode="single"
filteredValue="#{cratesView.filteredCrates}" selection="#{cratesView.selectedCrate}"
lazy="true" liveScroll="true" scrollRows="150"
widgetVar="cratesTbl" rowKey="#{crate.id}" scrollable="true" scrollHeight="550">
<p:column style="width:16px" exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="#{label['crate.col.grp']}" filterStyle="width:60px;" filterBy="#{crate.grp}" filterMatchMode="contains" width="60">
<h:outputText value="#{crate.grp}"/>
</p:column>
...additional columns of crate.
<p:rowExpansion >
<p:panelGrid columnClasses="label,value" >
<div class="remark-label"><b>#{label['crateview.toggle.remark']}</b>: <h:outputLabel value="#{crate.remark}"/></div>
<p:dataTable id='bTbl' var="bottle" value="#{cratesView.getBottles2Crate(crate)}"
widgetVar="bottleTbl" rowKey="#{bottle.id}" scrollable="true" scrollHeight="300">
<p:column headerText="#{label['bottle.col.grp']}" width="50">
<h:outputText value="#{bottle.grp}"/>
</p:column>
...additional columns of bottle
</p:dataTable>
</p:column>
</p:row>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
</h:form>
</ui:define>
and Bean:
#ManagedBean(name = "cratesView")
#ViewScoped
public class CrateView implements Serializable {
//object definitions
#PostConstruct
public void init() {
//init some objects
lazyModel = new LazyCrateDatamodel(cratesList);
}
public LazyDataModel<Crate> getLazyModel() {
return lazyModel;
}
public void setLazyModel(LazyCrateDatamodel lazyModel){
this.lazyModel = lazyModel;
}
public void setSelectedCrate(final Crate c){
this.selectedCrate = c;
}
public Crate getSelectedCrate() {
return this.selectedCrate;
}
public List<Crate> getFilteredCrates() {
return filteredCrates;
}
public void setFilteredCrates(List<Crate> filteredCrates) {
this.filteredCrates = filteredCrates;
}
public List<Bottle> getBottles2Crate(final Crate c)
{
int grp = c.getGrp(); //
return gProvider.getBottlesByCrate(calculated.getGrp(), 0);
}
}
Everything runs fine on the firstpage, opening the expansion shows correct data in the table. After loading the next 150 rows and scrolling back to e.g. the first row and opening the expansion the data of a wrong crate is loaded. cratesView.getBottles2Crate(crate) is called with a crate-object shifted by n*150(n - numbers of loadings). The object of the rowtoggling-event is not the same of the datamodel. On the other side setSelectedCrate gets the right object.
Do I have something misconfigurated or is there a hint in the docs using rowexpansion and lazyloading...
Thanks for some hints.
Edit: Correct some syntax.
Sorry for the missing information:
Mojarra JSF Implementation 2.3.0 (20170310-1214)
Primeface 6.2
I tested it parallel with a minimal version:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Lazy Test</title>
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon" />
</h:head>
<body>
<h:form id="crateTbl">
<p:dataTable rowExpandMode="single" id="cTbl" var="crate" value="#{lazyView.model}" selectionMode="single" selection="#{lazyView.selectedCrate}"
lazy="true" liveScroll="true" scrollRows="150"
widgetVar="cratesTbl" rowKey="#{crate.id}" scrollable="true" scrollHeight="550">
<p:column style="width:16px" exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="Kistengrp" width="60">
<h:outputText value="#{crate.grp}"/>
</p:column>
<p:column headerText="Kistennamen" width="250">
<h:outputText value="#{crate.name}"/>
</p:column>
<p:column headerText="Flaschengrp" width="100">
<h:outputText value="#{crate.bgrp}"/>
</p:column>
<p:rowExpansion >
<p:panelGrid columnClasses="label,value" >
<p:dataTable id='bTbl' var="bottle" value="#{lazyView.getBottlesByCrate(crate)}" widgetVar="bottleTbl" rowKey="#{bottle.id}" scrollable="true" scrollHeight="300">
<p:column headerText="Gruppe" width="50">
<h:outputText value="#{bottle.grp}"/>
</p:column>
<p:column headerText="Name" width="250">
<h:outputText value="#{bottle.name}"/>
</p:column>
<p:column headerText="Id" width="100">
<h:outputText value="#{bottle.id}"/>
</p:column>
</p:dataTable>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
</h:form>
</body>
</html>
Classes:
Testdata provider:
package de.test;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
#ManagedBean(name = "testservice")
#ApplicationScoped
public class AssortmentProvider {
private final static String[] NAMES = {"Uerige","Koelsch","Wasser","Saft","Limo","Cola","Kupfer","Messing"};
private final static int[] BGRPS = {1,12,15,20,24,25,26,30,100,112,155,200,201,242,250};
private final static int[] CGRPS = {1000,1020,1050,2000,2400,2500,2600,3000,1006,1120,1550,2050,2010,2420,2500};
private List<Crate> crates;
private List<Bottle> bottles;
#PostConstruct
public void init() {
this.createBottles();
this.createCrates();
}
public List<Crate> getCrates() { return crates; }
public List<Bottle> getBottles() { return bottles; }
public List createCrates() {
crates = new ArrayList<>();
for(int i=0;i<500;i++) {
int n = (int) (Math.random() * 8);
int g = (int) (Math.random() * 15);
int b = (int) (Math.random() * 15);
Crate c = new Crate(NAMES[n], i, CGRPS[g]);
c.setBgrp(BGRPS[b]);
crates.add(c);
}
return crates;
}
public List createBottles() {
bottles = new ArrayList<>();
for(int i=0;i<500;i++) {
int n = (int) (Math.random() * 8);
int b = (int) (Math.random() * 15);
Bottle btl = new Bottle("B_" + NAMES[n], i, BGRPS[b]);
bottles.add(btl);
}
return bottles;
}
}
Entities Crate:
package de.test;
public class Crate extends Entity {
private int bgrp;
public Crate(String name, int id, int cgrp) { super(name,id,cgrp); }
public int getBgrp() { return bgrp; }
public void setBgrp(int bgrp) { this.bgrp = bgrp; }
#Override
public String toString() { return "Crate{" + "name=" + name + ", id=" + id + ", grp=" + grp + ", bgrp=" + bgrp +'}'; }
}
next Bottle:
package de.test;
public class Bottle extends Entity {
public Bottle(String name, int id, int grp) { super(name,id,grp); }
#Override
public String toString() { return "Bottle{" + "name=" + name + ", id=" + id + ", grp=" + grp + '}'; }
}
next Entity:
package de.test;
public class Entity {
protected String name;
protected int id;
protected int grp;
public Entity(String name, int id, int grp) {
this.name = name;
this.id = id;
this.grp = grp;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getGrp() { return grp; }
public void setGrp(int grp) { this.grp = grp; }
}
next LazyView:
package de.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "lazyView")
#ViewScoped
public class LazyView implements Serializable {
#ManagedProperty("#{testservice}")
AssortmentProvider service;
List<Crate> crateList;
Crate selectedCrate;
LazyCrateModel model;
#PostConstruct
public void init() {
crateList = this.service.createCrates();
model = new LazyCrateModel(crateList);
}
public void setService(AssortmentProvider service) { this.service = service; }
public Crate getSelectedCrate() { return selectedCrate; }
public void setSelectedCrate(Crate selectedCrate) { this.selectedCrate = selectedCrate; }
public List<Crate> getCrateList() { return crateList; }
public void setCrateList(List<Crate> crateList) { this.crateList = crateList; }
public LazyCrateModel getModel() { return model; }
public List<Bottle> getBottlesByCrate(final Crate c) {
System.out.println(c);
List<Bottle> l = new ArrayList<>();
for(Bottle b : service.getBottles())
{
if( b.getGrp() == c.getBgrp())
l.add(b);
}
return l;
}
}
next LazyDatamodel:
package de.test;
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
public class LazyCrateModel extends LazyDataModel<Crate> {
private final List<Crate> list;
public LazyCrateModel(List<Crate> list) { this.list = list; }
#Override
public Integer getRowKey(Crate object) { return object.getId(); }
#Override
public List<Crate> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
this.setRowCount(list.size());
if(first + pageSize > list.size()) {
pageSize = list.size() - first;
}
List<Crate> sub = list.subList(first, first + pageSize);
return sub;
}
#Override
public Crate getRowData(String str) {
int idx = Integer.parseInt(str);
for(Crate c : list) {
if(c.getId() == idx)
return c;
}
return null;
}
}
It's the same behavior: After one loading scrolling to the beginning, the given crate is the 150 shifted crate, not crate[0].
Hope someone can verify this behavior.

Open details of a single row in a datatable in a new page

I have a datatable from database and I would like details of one of the rows appear in a new table when I click on the "OPEN" button as in the screenshot below.
When I click on the OPEN button I get "No records found " as in the next screenshot below
Here is part of the index.xhtml
//
APP WEB
<p:ajax event="rowEdit" listener="#{transaction.onRowEdit}" update=":form1:messages" />
<p:ajax event="rowEditCancel" listener="#{transaction.onRowCancel}" update=":form1:messages" />
<p:column headerText="Reference">
<p:commandLink value="#{c.reference}" action="/faces/global/SingleTx.xhtml" target="_blank" >
<f:setPropertyActionListener target="#{transaction.showSelectedTx(reference)}" value="#{c}" />
</p:commandLink>
</p:column>
<p:column headerText="Rartner">
#{c.pname}
</p:column>
<p:column headerText="Status">
#{c.fk_status}
</p:column>
<p:column headerText="Sender">
#{c.sendername}
</p:column>
<p:column headerText="Beneficiary">
#{c.beneficiaryname}
</p:column>
<p:column headerText="Amounts">
#{c.beneficiary_currency} #{c.beneficiary_amount}
</p:column>
<p:column headerText="Action">
<p:commandButton style="float:right" value="Print" >
<p:confirm header="#{cd.reference}" message="Are you sure?" icon="ui-icon-alert" />
<p:button value="Open" href="/faces/global/SingleTx.xhtml" target="_self" />
</p:commandButton>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:dialog modal="true" width="800px" height="400px" widgetVar="singletx"
id="dialog">
Name :#{transaction.showSelectedTx(reference)}
</p:dialog>
</h:form>
Here is the backing bean:
package com.mycompany.data;
/**
*
* #author bryan
*/
import conn.DBConnector;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "transaction")
#SessionScoped
public class TransactionBean implements Serializable {
//added
private static final long serialVersionUID = 1L;
public String reference;
public String fk_status;
public String sendername;
public String beneficiaryname;
public String beneficiary_currency;
public double beneficiary_amount;
public String pname;
Transaction user;
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getFk_status() {
return fk_status;
}
public void setFk_status(String fk_status) {
this.fk_status = fk_status;
}
public String getSendername() {
return sendername;
}
public void setSendername(String sendername) {
this.sendername = sendername;
}
public String getBeneficiaryname() {
return beneficiaryname;
}
public void setBeneficiaryname(String beneficiaryname) {
this.beneficiaryname = beneficiaryname;
}
public String getBeneficiary_currency() {
return beneficiary_currency;
}
public void setBeneficiary_currency(String beneficiary_currency) {
this.beneficiary_currency = beneficiary_currency;
}
public double getBeneficiary_amount() {
return beneficiary_amount;
}
public void setBeneficiary_amount(double beneficiary_amount) {
this.beneficiary_amount = beneficiary_amount;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
//resource injection
#Resource(name = "jdbc/primefaces")
//connect to DB and get customer list
public List<Transaction> getTransactionList() throws SQLException, ClassNotFoundException {
Connection con = null;
con = DBConnector.getDBConnection();
if (con == null) {
throw new SQLException("Can't get database connection");
}
PreparedStatement ps
= con.prepareStatement(
"select tx.reference,p.pname,ts.name, tx.sendername, tx.beneficiaryname, tx.beneficiary_currency,tx.beneficiary_amount from transaction_stage tx join transaction_status ts on tx.fk_status=ts.id join partner p on tx.fk_partner=p.id");
//get customer data from database
ResultSet result = ps.executeQuery();
List<Transaction> list = new ArrayList<Transaction>();
while (result.next()) {
Transaction cust = new Transaction();
cust.setReference(result.getString("reference"));
cust.setFk_status(result.getString("name"));
cust.setSendername(result.getString("sendername"));
cust.setBeneficiaryname(result.getString("beneficiaryname"));
cust.setBeneficiary_currency(result.getString("beneficiary_currency"));
cust.setBeneficiary_amount(result.getDouble("beneficiary_amount"));
cust.setPname(result.getString("pname"));
//store all data into a List
list.add(cust);
}
return list;
//added
}
//view single transaction
private List<Transaction> selectSingleTx;
public Transaction getUser() {
return user;
}
public void setUser(Transaction user) {
this.user = user;
}
public List<Transaction> getSelectSingleTx() {
return selectSingleTx;
}
public void setSelectSingleTx(List<Transaction> selectSingleTx) {
this.selectSingleTx = selectSingleTx;
}
public void showSelectedTx(String reference){
Connection con=DBConnector.getDBConnection();
if(con==null){
System.out.println("No db connection");
}
String ref=getReference();
try {
String q="select tx.reference,p.pname,ts.name, tx.sendername, tx.beneficiaryname, tx.beneficiary_currency,tx.beneficiary_amount from transaction_stage tx join transaction_status ts on tx.fk_status=ts.id join partner p on tx.fk_partner=p.id where tx.reference="+ref+"";
PreparedStatement ps=null;
ResultSet rs=null;
ps.setString(1, reference);
rs=ps.executeQuery();
display(rs);
} catch (Exception e) {
}
}
public void selectTx(String reference){
showSelectedTx(reference);
}
// to be implemented later
private static void display(ResultSet myRs) throws SQLException {
while (myRs.next()) {
String sendername = myRs.getString("sendername");
String beneficiaryname = myRs.getString("beneficiaryname");
//double salary = myRs.getDouble("salary");
String department = myRs.getString("department");
System.out.printf("%s, %s \n", sendername, beneficiaryname);
}
}
}
//
As per the Reference link, you need to include the value of c.reference in the link
value="#{c.reference}"
See JSF ViewParam from CommandButton
or
How to pass a parameter along with h:commandButton

Prime faces 5.0: custom filter in data table ignored

I'm trying to have a selectonemenu as filter option in a data table
I've done several tests, with no success
Now I'm trying to create a sample custom filter, with selectOneButton, with static fields, trying to simplify, but again it doesn't work
<p:column filterBy="#{sController.getStatus(se)}" headerText="Stato"
style="text-align:center;" sortBy="#{sController.getStatus(se)}"
filterMatchMode="exact"
>
<f:facet name="filter">
<p:selectOneButton onchange="PF('sDataTableWV').filter()">
<f:converter converterId="javax.faces.Boolean" />
<f:selectItem itemLabel="All" itemValue="" />
<f:selectItem itemLabel="Sold" itemValue="true" />
<f:selectItem itemLabel="Sale" itemValue="false" />
</p:selectOneButton>
</f:facet>
<img src="#{resource[sController.getStatus(se)]}" />
</p:column>
The facet is completely ignored, I see the usual input field instead
-------------- EDIT ------------------
As per request, I prepared a new page taking the source code of the showcase
here is the XHTML page
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Pagina di test</title>
</h:head>
<body>
<h3>Pagina di test</h3>
<h:form>
<p:dataTable var="car" value="#{dtFilterView.cars}" widgetVar="carsTable"
emptyMessage="No cars found with given criteria" filteredValue="#{dtFilterView.filteredCars}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="PF('carsTable').filter()" style="width:150px" placeholder="Enter keyword"/>
</p:outputPanel>
</f:facet>
<p:column filterBy="#{car.id}" headerText="Id" footerText="contains" filterMatchMode="contains">
<h:outputText value="#{car.id}" />
</p:column>
<p:column filterBy="#{car.year}" headerText="Year" footerText="lte" filterMatchMode="lte">
<f:facet name="filter">
<p:spinner onchange="PF('carsTable').filter()" styleClass="year-spinner">
<f:converter converterId="javax.faces.Integer" />
</p:spinner>
</f:facet>
<h:outputText value="#{car.year}" />
</p:column>
<p:column filterBy="#{car.brand}" headerText="Brand" footerText="exact" filterMatchMode="exact">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('carsTable').filter()" >
<f:selectItem itemLabel="Select One" itemValue="#{null}" noSelectionOption="true" />
<f:selectItems value="#{dtFilterView.brands}" />
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{car.brand}" />
</p:column>
<p:column filterBy="#{car.color}" headerText="Color" footerText="in" filterMatchMode="in">
<f:facet name="filter">
<p:selectCheckboxMenu label="Colors" onchange="PF('carsTable').filter()" panelStyle="width:125px" scrollHeight="150">
<f:selectItems value="#{dtFilterView.colors}" />
</p:selectCheckboxMenu>
</f:facet>
<h:outputText value="#{car.color}" />
</p:column>
<p:column filterBy="#{car.sold}" headerText="Status" footerText="equals" filterMatchMode="equals">
<f:facet name="filter">
<p:selectOneButton onchange="PF('carsTable').filter()">
<f:converter converterId="javax.faces.Boolean" />
<f:selectItem itemLabel="All" itemValue="" />
<f:selectItem itemLabel="Sold" itemValue="true" />
<f:selectItem itemLabel="Sale" itemValue="false" />
</p:selectOneButton>
</f:facet>
<h:outputText value="#{car.sold ? 'Sold': 'Sale'}" />
</p:column>
<p:column filterBy="#{car.price}" headerText="Price" footerText="custom (min)" filterFunction="#{dtFilterView.filterByPrice}">
<h:outputText value="#{car.price}">
<f:convertNumber currencySymbol="$" type="currency"/>
</h:outputText>
</p:column>
</p:dataTable>
</h:form>
</body>
</html>
here the Car.java
package controllers.test;
import java.io.Serializable;
public class Car implements Serializable {
public String id;
public String brand;
public int year;
public String color;
public int price;
public boolean sold;
public Car() {}
public Car(String id, String brand, int year, String color) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
}
public Car(String id, String brand, int year, String color, int price, boolean sold) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
this.price = price;
this.sold = sold;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public boolean isSold() {
return sold;
}
public void setSold(boolean sold) {
this.sold = sold;
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Car other = (Car) obj;
if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
return false;
}
return true;
}
}
then CarService.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
#ManagedBean(name = "carService")
#ApplicationScoped
public class CarService {
private final static String[] colors;
private final static String[] brands;
static {
colors = new String[10];
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
brands = new String[10];
brands[0] = "BMW";
brands[1] = "Mercedes";
brands[2] = "Volvo";
brands[3] = "Audi";
brands[4] = "Renault";
brands[5] = "Fiat";
brands[6] = "Volkswagen";
brands[7] = "Honda";
brands[8] = "Jaguar";
brands[9] = "Ford";
}
public List<Car> createCars(int size) {
List<Car> list = new ArrayList<Car>();
for(int i = 0 ; i < size ; i++) {
list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState()));
}
return list;
}
private String getRandomId() {
return UUID.randomUUID().toString().substring(0, 8);
}
private int getRandomYear() {
return (int) (Math.random() * 50 + 1960);
}
private String getRandomColor() {
return colors[(int) (Math.random() * 10)];
}
private String getRandomBrand() {
return brands[(int) (Math.random() * 10)];
}
public int getRandomPrice() {
return (int) (Math.random() * 100000);
}
public boolean getRandomSoldState() {
return (Math.random() > 0.5) ? true: false;
}
public List<String> getColors() {
return Arrays.asList(colors);
}
public List<String> getBrands() {
return Arrays.asList(brands);
}
}
and last FilterView.java
import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
#ManagedBean(name="dtFilterView")
#ViewScoped
public class FilterView implements Serializable {
private List<Car> cars;
private List<Car> filteredCars;
#ManagedProperty("#{carService}")
private CarService service;
#PostConstruct
public void init() {
cars = service.createCars(10);
}
public boolean filterByPrice(Object value, Object filter, Locale locale) {
String filterText = (filter == null) ? null : filter.toString().trim();
if(filterText == null||filterText.equals("")) {
return true;
}
if(value == null) {
return false;
}
return ((Comparable) value).compareTo(Integer.valueOf(filterText)) > 0;
}
public List<String> getBrands() {
return service.getBrands();
}
public List<String> getColors() {
return service.getColors();
}
public List<Car> getCars() {
return cars;
}
public List<Car> getFilteredCars() {
return filteredCars;
}
public void setFilteredCars(List<Car> filteredCars) {
this.filteredCars = filteredCars;
}
public void setService(CarService service) {
this.service = service;
}
}
The result is exactly the same, the filter are input field
I'm on glassfish 3.2
Sorry, I have my development environment with 5.0, but on production was 3.5
changing the library all worked

Reset p:tree selected values

I need to reset the selected values in a p:tree. I create a reset button in the form where i put my p:tree element. That button put the selected values of the tree as null values. In the backing bean the values are clear when i press this button. But in the interface even when I refresh the page the old selected value still marked. Here is my code:
p:tree
<p:tree id="treeClassifier"
value="#{navBarController.rootClassifier}"
var="node"
selectionMode="checkbox"
selection="#{navBarController.selectedClassifiers}"
style="height: 100px;width: 280px; margin-bottom: 0px; overflow: auto">
<p:treeNode expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{node.description}(#{node.code})"/>
</p:treeNode>
</p:tree>
Create the tree:
public TreeNode initTree(GenericTree<Classifier> tree) {
GenericTreeNode<Classifier> root = tree.getRoot();
TreeNode rootJSF = new DefaultTreeNode("root", null);
for (GenericTreeNode<Classifier> gnt : root.getChildren()) {
if (gnt.getData().getId() != -1) {
TreeNode childTree = new DefaultTreeNode(gnt.getData(), rootJSF);
//rootJSF.getChildren().add(childTree);
//f_aux(gnt, rootJSF);
addChildsToTree(gnt, childTree);
}
}
return rootJSF;
}
public void addChildsToTree(GenericTreeNode<Classifier> parent, TreeNode parentJSF) {
for (GenericTreeNode<Classifier> child : parent.getChildren()) {
TreeNode newNode = new DefaultTreeNode(child.getData(), parentJSF);
//parentJSF.getChildren().add(newNode);
addChildsToTree(child, newNode);
}
}
The reset function:
public void reset() {
....
this.selectedClassifiers = null;
}
What is wrong in my code?
You can achieve by below example which method resetSelectedNode is used to fresh values.
xhtml
<h:form>
<p:growl id="msgs" showDetail="true" escape="false"/>
<p:inputText value="#{treeSelectionView.input}" />
<h3 style="margin-top:0">Single</h3>
<p:tree value="#{treeSelectionView.root1}"
id="simpleSelection"
var="doc"
selectionMode="single"
selection="#{treeSelectionView.selectedNode}"
dynamic="true">
<p:treeNode expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{doc.name}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon-document">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="picture" icon="ui-icon-image">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="mp3" icon="ui-icon-video">
<h:outputText value="#{doc.name}" />
</p:treeNode>
</p:tree>
<p:commandButton value="Display"
update="msgs"
icon="ui-icon-newwin"
actionListener="#{treeSelectionView.displaySelectedSingle}"/>
<p:commandButton value="Reset"
update="simpleSelection"
icon="ui-icon-newwin"
process="#this"
actionListener="#{treeSelectionView.resetSelectedNode}" />
</h:form>
managedbean
#ManagedBean(name = "treeSelectionView")
#ViewScoped
public class SelectionView implements Serializable {
private TreeNode root1;
private TreeNode selectedNode;
private String input;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
#ManagedProperty("#{documentService}")
private DocumentService service;
#PostConstruct
public void init() {
root1 = service.createDocuments();
}
public TreeNode getRoot1() {
return root1;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void setService(DocumentService service) {
this.service = service;
}
public void displaySelectedSingle() {
System.out.println("input: " + input);
if (selectedNode != null) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", selectedNode.getData().toString());
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
public void resetSelectedNode(ActionEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ViewHandler viewHandler = application.getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, context.getViewRoot().getViewId());
context.setViewRoot(viewRoot);
context.renderResponse(); //Optional
}
}
See also: Clear Input Components
With these suggestions i realized that i need to reset the values from the selected array and update the nodes in the tree. So I made the following changes in my code:
public void reset() {
....
this.selectedClassifiers = null;
this.rootNode = initTree(tree);
}
public TreeNode initTree(GenericTree<Classifier> tree) {
GenericTreeNode<Classifier> root = tree.getRoot();
TreeNode rootJSF = new DefaultTreeNode("root", null);
rootJSF.setSelected(false);
for (GenericTreeNode<Classifier> gnt : root.getChildren()) {
if (gnt.getData().getId() != -1) {
TreeNode childTree = new DefaultTreeNode(gnt.getData(), rootJSF);
childTree.setSelected(false);
addChildsToTree(gnt, childTree);
}
}
return rootJSF;
}
public void addChildsToTree(GenericTreeNode<Classifier> parent, TreeNode parentJSF) {
for (GenericTreeNode<Classifier> child : parent.getChildren()) {
TreeNode newNode = new DefaultTreeNode(child.getData(), parentJSF);
newNode.setSelected(false);
addChildsToTree(child, newNode);
}
}
With these changes I fix my code.
Another example here.
XHTML
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:facet name="first">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta name="viewport"
content="user-scalable=no,
width=device-width,
initial-scale=1.0,
maximum-scale=1.0"/>
</f:facet>
<title>Tree provides three selection modes, "single", "multiple" and "checkbox".</title>
</h:head>
<h:body id="bodyView">
<h:form>
<p:growl id="msgs" showDetail="true" escape="false"/>
<h3 style="margin-top:0">Single</h3>
<p:tree value="#{treeSelectionView.root1}"
id="simpleSelection"
var="doc"
selectionMode="single"
selection="#{treeSelectionView.selectedNode}">
<p:treeNode expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{doc.name}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon-document">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="picture" icon="ui-icon-image">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="mp3" icon="ui-icon-video">
<h:outputText value="#{doc.name}" />
</p:treeNode>
</p:tree>
<p:commandButton value="Display"
update="msgs"
icon="ui-icon-newwin"
actionListener="#{treeSelectionView.displaySelectedSingle}"/>
<p:commandButton value="Reset"
update="simpleSelection"
icon="ui-icon-newwin"
process="#this"
actionListener="#{treeSelectionView.resetSelectedNode}" />
<h3>Multiple with metakey</h3>
<p:tree id="multipleSelection"
value="#{treeSelectionView.root1}"
var="doc"
selectionMode="multiple"
selection="#{treeSelectionView.selectedNodes1}">
<p:treeNode expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{doc.name}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon-document">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="picture" icon="ui-icon-image">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="mp3" icon="ui-icon-video">
<h:outputText value="#{doc.name}" />
</p:treeNode>
</p:tree>
<p:commandButton value="Display"
update="msgs"
icon="ui-icon-newwin"
actionListener="#{treeSelectionView.displaySelectedMultiple(treeSelectionView.selectedNodes1)}"/>
<p:commandButton value="Reset"
update="multipleSelection"
icon="ui-icon-newwin"
process="#this"
actionListener="#{treeSelectionView.resetSelectedNode}" />
<h3>Multiple with Checkbox</h3>
<p:tree id="checkboxSelection"
value="#{treeSelectionView.root1}"
var="doc"
selectionMode="checkbox"
selection="#{treeSelectionView.selectedNodes2}">
<p:treeNode icon="ui-icon-note">
<h:outputText value="#{doc.name}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon-document">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="picture" icon="ui-icon-image">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="mp3" icon="ui-icon-video">
<h:outputText value="#{doc.name}" />
</p:treeNode>
</p:tree>
<p:commandButton value="Display"
update="msgs"
icon="ui-icon-newwin"
actionListener="#{treeSelectionView.displaySelectedMultiple(treeSelectionView.selectedNodes2)}"/>
<p:commandButton value="Reset"
update="checkboxSelection"
icon="ui-icon-newwin"
process="#this"
actionListener="#{treeSelectionView.resetSelectedNode}" />
</h:form>
</h:body>
</html>
managedbean treeSelectionView
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.application.ViewHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.model.TreeNode;
import org.primefaces.showcase.service.DocumentService;
#ManagedBean(name = "treeSelectionView")
#ViewScoped
public class SelectionView implements Serializable {
private TreeNode root1;
private TreeNode root2;
private TreeNode root3;
private TreeNode selectedNode;
private TreeNode[] selectedNodes1;
private TreeNode[] selectedNodes2;
#ManagedProperty("#{documentService}")
private DocumentService service;
#PostConstruct
public void init() {
root1 = service.createDocuments();
root2 = service.createDocuments();
root3 = service.createDocuments();
}
public TreeNode getRoot1() {
return root1;
}
public TreeNode getRoot2() {
return root2;
}
public TreeNode getRoot3() {
return root3;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public TreeNode[] getSelectedNodes1() {
return selectedNodes1;
}
public void setSelectedNodes1(TreeNode[] selectedNodes1) {
this.selectedNodes1 = selectedNodes1;
}
public TreeNode[] getSelectedNodes2() {
return selectedNodes2;
}
public void setSelectedNodes2(TreeNode[] selectedNodes2) {
this.selectedNodes2 = selectedNodes2;
}
public void setService(DocumentService service) {
this.service = service;
}
public void displaySelectedSingle() {
if (selectedNode != null) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", selectedNode.getData().toString());
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
public void displaySelectedMultiple(TreeNode[] nodes) {
if (nodes != null && nodes.length > 0) {
StringBuilder builder = new StringBuilder();
for (TreeNode node : nodes) {
builder.append(node.getData().toString());
builder.append("<br />");
}
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", builder.toString());
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
public void resetSelectedNode(ActionEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ViewHandler viewHandler = application.getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, context.getViewRoot().getViewId());
context.setViewRoot(viewRoot);
context.renderResponse(); //Optional
}
}
managedbean documentService
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.primefaces.showcase.domain.Document;
#ManagedBean(name = "documentService")
#ApplicationScoped
public class DocumentService {
public TreeNode createDocuments() {
TreeNode root = new DefaultTreeNode(new Document("Files", "-", "Folder"), null);
TreeNode documents = new DefaultTreeNode(new Document("Documents", "-", "Folder"), root);
TreeNode pictures = new DefaultTreeNode(new Document("Pictures", "-", "Folder"), root);
TreeNode movies = new DefaultTreeNode(new Document("Movies", "-", "Folder"), root);
TreeNode work = new DefaultTreeNode(new Document("Work", "-", "Folder"), documents);
TreeNode primefaces = new DefaultTreeNode(new Document("PrimeFaces", "-", "Folder"), documents);
//Documents
TreeNode expenses = new DefaultTreeNode("document", new Document("Expenses.doc", "30 KB", "Word Document"), work);
TreeNode resume = new DefaultTreeNode("document", new Document("Resume.doc", "10 KB", "Word Document"), work);
TreeNode refdoc = new DefaultTreeNode("document", new Document("RefDoc.pages", "40 KB", "Pages Document"), primefaces);
//Pictures
TreeNode barca = new DefaultTreeNode("picture", new Document("barcelona.jpg", "30 KB", "JPEG Image"), pictures);
TreeNode primelogo = new DefaultTreeNode("picture", new Document("logo.jpg", "45 KB", "JPEG Image"), pictures);
TreeNode optimus = new DefaultTreeNode("picture", new Document("optimusprime.png", "96 KB", "PNG Image"), pictures);
//Movies
TreeNode pacino = new DefaultTreeNode(new Document("Al Pacino", "-", "Folder"), movies);
TreeNode deniro = new DefaultTreeNode(new Document("Robert De Niro", "-", "Folder"), movies);
TreeNode scarface = new DefaultTreeNode("mp3", new Document("Scarface", "15 GB", "Movie File"), pacino);
TreeNode carlitosWay = new DefaultTreeNode("mp3", new Document("Carlitos' Way", "24 GB", "Movie File"), pacino);
TreeNode goodfellas = new DefaultTreeNode("mp3", new Document("Goodfellas", "23 GB", "Movie File"), deniro);
TreeNode untouchables = new DefaultTreeNode("mp3", new Document("Untouchables", "17 GB", "Movie File"), deniro);
return root;
}
}
domain
import java.io.Serializable;
public class Document implements Serializable, Comparable<Document> {
private String name;
private String size;
private String type;
public Document(String name, String size, String type) {
this.name = name;
this.size = size;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//Eclipse Generated hashCode and equals
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Document other = (Document) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (size == null) {
if (other.size != null) {
return false;
}
} else if (!size.equals(other.size)) {
return false;
}
if (type == null) {
if (other.type != null) {
return false;
}
} else if (!type.equals(other.type)) {
return false;
}
return true;
}
#Override
public String toString() {
return name;
}
public int compareTo(Document document) {
return this.getName().compareTo(document.getName());
}
}
This is what I do in my projects :
I define this method, and call it whereever I want.
public static void resetAllInputChildren(String parentId) {
FacesContext currentInstance = FacesContext.getCurrentInstance();
if (currentInstance != null && currentInstance.getViewRoot() != null) {
RequestContext.getCurrentInstance().reset(parentId);
}
}
instead of the parentId, I normally set the form id. but it is your choice, you can set any component Id as the parentId.
One more thing, this is not a primefaces issue, the solution I suggested, applies to all jsf2 projects, and all input components.

Action of CommandLink/CommandButton in p:treeTable is not invoked

I download primefaces 3.1, add to my project tried to add a commandButton/commandLink into a column of a treeTable
but action of commandButton/commandLink in a column is not invoked except the root row.
What may the problem be? Thanks
EDIT:
treeTable in xhtml:
<p:treeTable var="catalog" value="#{catalogSelectBean.root}" lazy="true" selection="#{catalogSelectBean.selectedNode}" selectionMode="single">
<p:column>
<f:facet name="header">
<h:outputText value="Katalog Name" />
</f:facet>
<h:outputText value="#{catalog.name}" />
</p:column>
<p:column width="100">
<f:facet name="header">
<h:outputText value="Katalog Desc"/>
</f:facet>
<h:outputText value="#{catalog.description}"/>
</p:column>
<p:column>
<p:commandButton action="#{formProductRelationView.updateProductListForSelectedCatalog()}"
update=":main_form:selectProductTable"
value="Bring Products">
</p:commandButton>
</p:column>
</p:treeTable>
Bean:
#Component("catalogSelectBean")
#Scope("request")
public class CatalogSelectBean implements Serializable {
private static final long serialVersionUID = 1L;
#Autowired
private CatalogService catalogService;
private TreeNode root;
private TreeNode selectedNode;
private DualListModel<Catalog> pickListCatalogs;
public TreeNode getRoot() {
return root;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void onNodeSelect(NodeSelectEvent event) {
Catalog g = (Catalog)event.getTreeNode().getData();
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", g.getName());
FacesContext.getCurrentInstance().addMessage(null, message);
}
public CatalogSelectBean() {
}
#PostConstruct
public void unLoad(){
createRoot();
createPickListModel();
}
private void createPickListModel() {
//Players
List<Catalog> source = catalogService.loadChilds(catalogService.getRootCatalog());
List<Catalog> target = new ArrayList<Catalog>();
pickListCatalogs = new DualListModel<Catalog>(source, target);
}
private void createRoot() {
Catalog g = null ;
g = catalogService.getRootCatalog();
root = new DefaultTreeNode("Root", null);
TreeNode caRoot = new DefaultTreeNode(g,root);
generateTree(caRoot,g);
}
private void generateTree(TreeNode subRoot, Catalog g) {
for(Catalog p : g.getChildCatalogs()){
TreeNode node0 = new DefaultTreeNode(p,subRoot);
if(p.getChildCatalogs()!= null && p.getChildCatalogs().size()>0)
generateTree(node0, p);
}
}
public void resetTree() {
root.setSelected(false);
}
public DualListModel<Catalog> getPickListCatalogs() {
return pickListCatalogs;
}
}
Also i have a formProductRelationView bean which has the updateProductListForSelectedCatalog() method.
Thanks for attention.