JSF How to pass the value of a CommandButton in bean [duplicate] - primefaces

I would like to download in primefaces a file whose name can vary.
Here is the code for the controller
#ManagedBean(name="fileDownloadController", eager = true)
#ViewScoped
public class FileDownloadController implements Serializable{
private StreamedContent file;
private String fileName;
public FileDownloadController() {
System.out.println("FileDownloadController sans arg");
System.out.println("getFileName:" + fileName);
InputStream stream = null;
try {
stream = new FileInputStream("D:/myFileDir/"+fileName);
} catch (FileNotFoundException ex) {
Logger.getLogger(FileDownloadController.class.getName()).log(Level.SEVERE, null, ex);
}
file = new DefaultStreamedContent(stream, "image/jpg", fileName);
}
}
And here is the xhtml
<c:forEach items="#{myBean.files}" var="file" >
<p:row>
<p:column>
<p:commandButton id="downloadLink" value="#{file.fileName}" ajax="false" onclick="PrimeFaces.monitorDownload(start, stop)" icon="ui-icon-arrowthichk-s" >
<f:setPropertyActionListener target="#{fileDownloadController.fileName}" value="#{file.fileName}"/>
<p:fileDownload value="#{fileDownloadController.file}" />
</p:commandButton>
</p:column>
</p:row>
</c:forEach>
The problem is that in the controller the fileName is null, hence the f:setPropertyActionListener is not configured properly.
However, I can't find a solution.

Why not to pass the fileName directly ...
Bean
#ManagedBean(name="fileDownloadController", eager = true)
#ViewScoped
public class FileDownloadController implements Serializable{
public StreamedContent generateFile(String fileName) {
InputStream stream = null;
try {
stream = new FileInputStream("D:/myFileDir/"+fileName);
} catch (FileNotFoundException ex) {
}
return new DefaultStreamedContent(stream, "image/jpg", fileName);
}
}
XHTML
<p:commandButton id="downloadLink" value="#{file.fileName}"
ajax="false" onclick="PrimeFaces.monitorDownload(start, stop)"
icon="ui-icon-arrowthichk-s" >
<p:fileDownload value="#{fileDownloadController.generateFile(file.fileName)}" />
</p:commandButton>
Hope this helps.

Related

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

Use List for source in datatable with lazyLoading

I have the list with very data. I want to show data in Primeface data table with lazy loading ability. now I show data normal in data Table, but it is slow.
How can use lazy loading ability?
XHTML File :
<ui:composition template="template.xhtml">
<ui:define name="content">
<p:panel id="pnlLogInformationPage">
<h:form id="logInformation">
<div class="contentContainer-full-left">
<p:dataTable var="log" value="#{logInformationMB.logInformationList}" id="logTable"
width="100%" liveResize="true">
<p:column headerText="ID" sortBy="Id">
<h:outputText value="#{logInformation.Id}" />
</p:column>
<p:column headerText="Name" sortBy="Name">
<h:outputText value="#{logInformation.Name}" />
</p:column>
</p:dataTable>
</div>
</h:form>
</p:panel>
</ui:define>
ManageBean File:
#ManagedBean(name = "logInformationMB")
#ViewScoped
public class LogManagedBean implements Serializable {
#PostConstruct
public void initComponents() {
loadLogInformation();
}
public List<LogInformationDTO> getLogInformationList() {
return logInformationList;
}
public void setLogInformationList(final List<LogInformationDTO> pLogInformationList) {
logInformationList = pLogInformationList;
}
public void loadLoagInformation(final ComponentSystemEvent event) {
setLogLInformationlist(getLogInformationList();
}
public void loadInformationProtokolle() {
loadInformationProtokolle(null);
}
public List<LogInformationDTO> getLogInformation() {
final List<LogInformationDTO> lcResult = new ArrayList<LogInformationDTO>();
....
return lcResult;
}
}
According to your code, you didn't use lazyloading. you just get all your datas.
It will be slow when your data is too big.
See my steps below:
1- Instead of using #{logInformationMB.logInformationList}, you need to create new class which extend LazyDataModel class and create a service that can get data page by page.
public class LogInformationDataModel extends LazyDataModel<LogInformationDTO> {
private List<LogInformationDTO> logInformationList;
private LogInformationService logInformationService = new LogInformationService();
#Override
public List<LogInformationDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
// TODO implement sort
setRowCount(logInformationService.count(filters));
logInformationList = logInformationService.list(first / pageSize, pageSize, sortField, sort, filters);
return logInformationList;
}
#Override
public LogInformationDTO getRowData(String rowKey) {
for(LogInformationDTO logInformation : logInformationList) {
if(logInformation.getId().equals(rowKey))
return logInformation;
}
return null;
}
#Override
public Object getRowKey(LogInformationDTO logInformation) {
return logInformation.getId();
}
}
2- Register data model in your Manage bean
#ManagedBean(name = "logInformationMB")
#ViewScoped
public class LogManagedBean implements Serializable {
private LogInformationDataModel dataModel = new LogInformationDataModel();
public LogInformationDataModel getDataModel() {
return dataModel;
}
}
3- Add lazy attribe (lazy="true") to your p:dataTable and using pagination
<p:dataTable var="log" value="#{logInformationMB.dataModel}" var="logInformation" id="logTable"
width="100%"
lazy="true"
paginator="true"
paginatorPosition="bottom"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,50,100"
>
<p:column headerText="ID" sortBy="Id">
<h:outputText value="#{logInformation.Id}" />
</p:column>
<p:column headerText="Name" sortBy="Name">
<h:outputText value="#{logInformation.Name}" />
</p:column>
</p:dataTable>
I Hope my answer could solve your issue.
Below is the link you can check :
Primefaces lazydatamodel

How to keep selected row after dialog closes Primefaces

In Primefaces 5.2, Glassfish 4.0, I am developping a simple CRUD. I have 2 distinct issues related to row selection.
The user clicks on a row in the datatable, this row is highlighted, the user selects "Edit" menu in the contextual menu, a modal window is opened.
1/ When the user press "Cancel" button in the modal window, the dialog is correctly closed. But then if the user selects another row in the datatable, the values displayed in the new modal window corresponds to the first previous selection. How to update the selected values?
2/ When the user press "OK" button in the modal window, the dialog is correctly closed, the datatable is correctly updated. But the updated row in the datatable is not anymore highlighted, the user doesn't know which row has just been updated. Is there a way to keep highlighted the lastly updated row (but to reinitialize the selected values for futher selection) until next click on a row, and in parallel of other focused row?
searchCompany.xhtml code is:
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<p:contextMenu for="table">
<p:menuitem value="View" update="detail" icon="ui-icon-search" oncomplete="PF('companyDialog').show()"/>
<p:menuitem value="Delete" update="table" icon="ui-icon-close" actionListener="#{dtContextMenuView.deleteCompany}"/>
</p:contextMenu>
<p:dataTable
id="table"
value="#{companyBean.allCompanies}"
var="company"
editable="true"
editmode="row"
widgetVar="cellCompanies"
sortBy="#{company.name}"
scrollable="true"
scrollWidth="1024"
scrollHeight="300"
rowKey="#{company.id}"
selection="#{companyBean.selectedCompany}"
selectionMode="single">
<!-- above: by default table is sorted by Company name -->
<!-- above: to freeze the 2 first columns : frozenColumns="2"-->
<p:column
style="width:150px"
sortBy="#{company.name}"
filterBy="#{company.name}"
filterMatchMode="contains">
<!-- Column is sortable -->
<f:facet name="header">
#{msg['name']} <!-- Title of the column -->
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{company.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{company.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
(..)
</p:dataTable>
<p:dialog header="#{msg['detail']}" widgetVar="companyDialog" modal="true" showEffect="fade" resizable="false">
<p:panel id="detail" >
<p:panelGrid columns="2" rendered="#{not empty companyBean.selectedCompany}">
<h:outputText value="#{msg['name']}:" />
<p:inputText value="#{companyBean.selectedCompany.name}" />
<h:outputText value="#{msg['contact']}:" />
<p:inputText value="#{companyBean.selectedCompany.contact}" />
</p:panelGrid>
<p:commandButton action="#{companyBean.updateCompanyEnd}" value='#{msg.OK}' oncomplete="PF('companyDialog').hide();" update="table, :form:msgs"/>
<p:commandButton value='#{msg.cancel}' onclick="PF('companyDialog').hide();"/>
</p:panel>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
The bean code is :
package com.sdzee.bean;
#ManagedBean
#ViewScoped
public class CompanyBean implements Serializable {
private static final long serialVersionUID = 1L;
private static final String CREATE_COMPANY = "createCompany";
private static final String DELETE_COMPANY = "deleteCompany";
private static final String UPDATE_COMPANY = "updateCompany";
private static final String LIST_ALL_COMPANIES = "searchCompany";
private static final String STAY_IN_THE_SAME_PAGE = null;
#EJB
private CompanyFacade companyFacade;
private Company company;
private List<Company> AllCompanies;
#PostConstruct
public void init() {
AllCompanies = companyFacade.findAll();
}
private Company selectedCompany;
public Company getCompany() {
if(company == null){
company = new Company();
}
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public List<Company> getAllCompanies() {
return AllCompanies;
}
public String updateCompanyEnd(){
try {
Company comp = selectedCompany;
companyFacade.update(comp);
} catch (EJBException e) {
FacesContext context = FacesContext.getCurrentInstance();
String texte = context.getApplication().evaluateExpressionGet(context, "#{msg['error']}", String.class);
sendErrorMessageToUser(texte+e);
return STAY_IN_THE_SAME_PAGE;
}
FacesContext context = FacesContext.getCurrentInstance();
String texte = context.getApplication().evaluateExpressionGet(context, "#{msg['update.successful']}", String.class);
FacesMessage message = new FacesMessage(texte, selectedCompany.getName());
FacesContext.getCurrentInstance().addMessage(null, message);
this.selectedCompany = company;
return LIST_ALL_COMPANIES;
}
public String deleteCompanyStart(){
return DELETE_COMPANY;
}
public String deleteCompanyEnd(){
try {
companyFacade.delete(company);
} catch (EJBException e) {
sendErrorMessageToUser("Error. Call the ADM");
return STAY_IN_THE_SAME_PAGE;
}
FacesContext context = FacesContext.getCurrentInstance();
String texte = context.getApplication().evaluateExpressionGet(context, "#{msg['delete.successful']}", String.class);
FacesMessage message = new FacesMessage(texte, company.getName());
FacesContext.getCurrentInstance().addMessage(null, message);
//sendInfoMessageToUser("Operation Complete: Delete");
return LIST_ALL_COMPANIES;
}
public String createCompanyStart(){
return CREATE_COMPANY;
}
public String createCompanyEnd(){
try {
companyFacade.save(company);
} catch (EJBException e) {
sendErrorMessageToUser("Error. Check if the weight is above 0 or call the adm");
return STAY_IN_THE_SAME_PAGE;
}
sendInfoMessageToUser("Operation Complete: Create");
return LIST_ALL_COMPANIES;
}
public String listAllCompanies(){
return LIST_ALL_COMPANIES;
}
private void sendInfoMessageToUser(String message){
FacesContext context = getContext();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
}
private void sendErrorMessageToUser(String message){
FacesContext context = getContext();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
}
private FacesContext getContext() {
FacesContext context = FacesContext.getCurrentInstance();
return context;
}
public Company getSelectedCompany() {
return selectedCompany;
}
public void setSelectedCompany(Company selectedCompany) {
this.selectedCompany = selectedCompany;
}
}

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.