I'm new in Richfaces framework which I'm going to use in the nearest project in my job.
I've created some simple example in which I have rich:dataTable and I'm trying to make column sorted. I've read in the tutorial ( http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/rich_column.html ) that everything what I need is to type "sortBy" parameter to the "rich:column" tag . Unfortunately columns can't be sort. Can anybody help me? Below source code of my simple app :
<ui:composition 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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<f:view>
<h:head></h:head>
<h:body>
<rich:panel header="Richfaces dataTable">
<rich:dataTable value="#{TaskListBean.dataList}" var="dataItem"
rows="4" columnClasses="50,100,100,100"
onRowMouseOver="this.style.backgroundColor='#B5F3FB'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.rowBackgroundColor}'"
width="350">
<f:facet name="caption">
<h:outputText value="This is the caption" />
</f:facet>
<f:facet name="header">
<h:outputText value="Trouble Ticket Systems" />
</f:facet>
<rich:column colspan="4">
<h:outputText value="Trouble Tickets opened" />
</rich:column>
<rich:column sortBy="#{dataItem.taskInstanceId}">
<f:facet name="header">Ticket Id</f:facet>
<h:outputText value="#{dataItem.taskInstanceId}" />
</rich:column>
<rich:column sortBy="#{dataItem.taskNode}">
<f:facet name="header">Status</f:facet>
<h:outputText value="#{dataItem.taskNode}" />
</rich:column>
<rich:column sortBy="#{dataItem.actorId}">
<f:facet name="header">Actor</f:facet>
<h:outputText value="#{dataItem.actorId}" />
</rich:column>
<rich:column>
<f:facet name="header">Description</f:facet>
<h:outputText value="#{dataItem.description}" />
</rich:column>
<f:facet name="footer">
<h:outputText value="This is the footer" />
</f:facet>
</rich:dataTable>
</rich:panel>
</h:body>
</f:view>
Menaged Bean of my app:
package richfacesr;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
#ManagedBean(name = "manager")
public class TaskListBean implements Serializable {
private ArrayList dataList;
public void loadDataList() {
dataList = new ArrayList();
TaskListData data1 = new TaskListData();
data1.setTaskInstanceId(1000l);
data1.setActorId("Willy smith");
data1.setTaskNode("In Charge");
data1.setDescription("CR 123456");
TaskListData data2 = new TaskListData();
data2.setTaskInstanceId(1001l);
data2.setActorId("Frank Sinatra");
data2.setTaskNode("Rejected");
data2.setDescription("CR 654321");
dataList.add(data1);
dataList.add(data2);
}
public List<TaskListData> getDataList() {
loadDataList();
return dataList;
}
}
and the object:
package richfacesr;
import java.util.ArrayList;
import java.util.List;
public class TaskListData {
private String taskNode;
private long taskInstanceId;
private String actorId;
private String description;
public String getActorId() {
return actorId;
}
public void setActorId(String actorId) {
this.actorId = actorId;
}
public String getTaskNode() {
return taskNode;
}
public void setTaskNode(String currentNode) {
this.taskNode = currentNode;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public long getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(long taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
}
Taken from the Richfaces 4 documentation, built in sorting for dataTables does not work.
The built-in sort controls are only available with the extendedDataTable component. Support for built-in sort controls in the dataTable component will be added in a subsequent release.
It did work in Richfaces 3, but it seems that they have changed a bit, so that this feature is currently not working in Richfaces 4, out of the box.
Although you say that you use Richfaces 5, which is Alpha1, I doubt that this feature is already in there. So you will need to write some code for yourself.
Looking a the Richfaces 4 showcase about table sorting you need to
put your managed bean into ViewScope - otherwise the unsorted list will be created again and again
move your loadDataList out of getDataList() into the constuctor or annotate it with #PostConstruct - otherwise the unsorted list will be created again and again
make your TaskListData Serializable
add a sort method to your TaskListBean - do the sorting there - maybe as described in Sort ArrayList of custom Objects by property
check the name of your ManagedBean TaskListBean - in the code you call it manager, but in your xhtml you call it TaskListBean
Here is my tuned version of your xhtml
<f:view>
<h:head />
<h:body>
<h:form>
<rich:dataTable id="table" var="dataItem"
value="#{manager.dataList}" width="350">
<rich:column id="ticketId" sortBy="#{dataItem.taskInstanceId}">
<f:facet name="header">
<a4j:commandLink value="Ticket Id" render="table"
action="#{manager.sortBy('Ticket Id')}" />
</f:facet>
<h:outputText value="#{dataItem.taskInstanceId}" />
</rich:column>
<rich:column sortBy="#{dataItem.taskNode}">
<f:facet name="header">
<a4j:commandLink value="Status" render="table"
action="#{manager.sortBy('Status')}" />
</f:facet>
<h:outputText value="#{dataItem.taskNode}" />
</rich:column>
<rich:column sortBy="#{dataItem.actorId}">
<f:facet name="header">
<a4j:commandLink value="Actor" render="table"
action="#{manager.sortBy('Actor')}" />
</f:facet>
<h:outputText value="#{dataItem.actorId}" />
</rich:column>
<rich:column>
<f:facet name="header">
<a4j:commandLink value="Description" render="table"
action="#{manager.sortBy('Description')}" />
</f:facet>
<h:outputText value="#{dataItem.description}" />
</rich:column>
</rich:dataTable>
</h:form>
</h:body>
</f:view>
My tuned version of your TaskListBean
import java.io.Serializable;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.faces.bean.*;
#ViewScoped
#ManagedBean(name="manager")
public class TaskListBean implements Serializable {
private ArrayList<TaskListData> dataList;
#PostConstruct
public void loadDataList() {
dataList = new ArrayList<TaskListData>();
TaskListData data1 = new TaskListData();
data1.setTaskInstanceId(1000l);
data1.setActorId("Willy smith");
data1.setTaskNode("In Charge");
data1.setDescription("CR 123456");
TaskListData data2 = new TaskListData();
data2.setTaskInstanceId(1001l);
data2.setActorId("Frank Sinatra");
data2.setTaskNode("Rejected");
data2.setDescription("CR 654321");
dataList.add(data1);
dataList.add(data2);
}
public void sortBy(String aColumn) {
System.out.println("sort by: " + aColumn);
// TODO sort the list by that attribute
}
public List<TaskListData> getDataList() {
return dataList;
}
}
Related
I want to get some information about contacts and display them in a table. I used two managed beans named by PersonalContact and BusinessContact and one abstract class named by Contact including firstName, lastName, ID, email and mphone attributes which derives from.Also, one generic class to add beans to an arraylist. I put here just BusinessContact as a bean, business as XHTML and tableBusiness as a table and generic class AddressBook, files of personal is parallel of them.
Inputs getting from screen are assigned to attributes of beans but when the beans go to Arraylist to be added, its content becomes null. Why is that? Is that about scopes?
Here is my bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class BusinessContact extends Contact{
private String companyName,workPhone;
public BusinessContact() {}
public BusinessContact(String companyName, String workPhone, String ID, String firstName, String lastName, String email, String mphone) {
super(ID, firstName, lastName, email, mphone);
this.companyName = companyName;
this.workPhone = workPhone;
}
/**
* Creates a new instance of BusinessContact
*/
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getWorkPhone() {
return workPhone;
}
public void setWorkPhone(String workPhone) {
this.workPhone = workPhone;
}
}
Here is my business.xhtml:
<?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://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Contact</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2">
First Name:
<h:inputText id="firstName" required="true"
requiredMessage="Can not be blank" value="#{businessContact.firstName}">
</h:inputText>
ID:
<h:inputText id="id" required="true"
requiredMessage="Can not be blank" value="#{businessContact.ID}">
</h:inputText>
Last Name:
<h:inputText id="lastName" required="true"
requiredMessage="Can not be blank" value="#{businessContact.lastName}">
</h:inputText>
E-mail:
<h:inputText id="email" required="true"
requiredMessage="Can not be blank" value="#{businessContact.email}">
</h:inputText>
Mobile Phone:
<h:inputText id="mphone" required="true"
requiredMessage="Can not be blank" value="#{businessContact.mphone}">
</h:inputText>
Company Name:
<h:inputText id="companyName" required="true"
requiredMessage="Can not be blank" value="#{businessContact.companyName}">
</h:inputText>
Work Phone:
<h:inputText id="workPhone" required="true"
requiredMessage="Can not be blank" value="#{businessContact.workPhone}">
</h:inputText>
</h:panelGrid>
<h:commandButton value="Add" id="add" action="#{addressBook.add(BusinessContact)}"></h:commandButton>
<h:commandButton value="Delete" id="delete" action="#{addressBook.remove(BusinessContact)}"></h:commandButton>
<h:outputLink id="t" value="tableBusiness.xhtml"> Click see the table</h:outputLink>
<ui:debug hotkey="k" rendered="true"/>
</h:form>
</h:body>
This is my generic class for putting beans to an arraylist:
import java.util.ArrayList;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class AddressBook <T extends Contact> {
private ArrayList<T> list = new ArrayList<T>();
T clas;
public ArrayList<T> getList() {
return list;
}
public void setList(ArrayList<T> list) {
this.list = list;
}
public void add(T obj) {
this.clas=obj;
//System.out.println(obj.getFirstName()+" ");
list.add(obj);
}
public void remove(T obj)
{
list.remove(obj);
}
/**
* Creates a new instance of AddressBook
*/
public AddressBook() {}
}
And lastly, this xhmtl for displaying arraylist in table:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form>
"#{businessContact.firstName}"
<h:dataTable value="#{addressBook.list}" var="BusinessContact">
<h:column>
<f:facet name="header">
First Name
</f:facet>
<h:outputText value="#{businessContact.firstName}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
Last Name
</f:facet>
#{businessContact.lastName}
</h:column>
<h:column>
<f:facet name="header">
Mobile Phone
</f:facet>
#{businessContact.mphone}
</h:column>
<h:column>
<f:facet name="header">
E-mail
</f:facet>
#{businessContact.email}
</h:column>
<h:column>
<f:facet name="header">
Company Name
</f:facet>
#{businessContact.companyName}
</h:column>
<h:column>
<f:facet name="header">
Work Phone
</f:facet>
#{businessContact.workPhone}
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
You are naming the var="BusinessContact" but trying to use it as "businessContact"
Change this line
<h:dataTable value="#{addressBook.list}" var="BusinessContact">
to this
<h:dataTable value="#{addressBook.list}" var="businessContact">
I am trying to pass a parameter (a user's id from a datatable) from one page to the next where I am using it (showing the user's details). The problem is that I can not get it. What am I missing? What am I doing wrong? I am using PrimeFaces 5 and JSF 2.2 (also Hibernate 4). Is there any way that I can have the parameter #PostConstruct so that I can load the user's details immediately?
The first page with the datable
<h:form id="manageUserForm" prependId="false">
<p:growl id="messages" showDetail="true" life="20000"/>
<p:dataTable id="usersTable" var="user" value="#{manageUsers.users}">
<f:facet name="header">
#{pvtmsg.registeredUsers}
</f:facet>
<p:column headerText="ID">
<h:outputText value="#{user.id}" />
</p:column>
<p:column headerText="#{pvtmsg.username}">
<h:outputText value="#{user.username}" />
</p:column>
<p:column headerText="#{pvtmsg.firstname}">
<h:outputText value="#{user.firstname}" />
</p:column>
<p:column headerText="#{pvtmsg.lastname}">
<h:outputText value="#{user.lastname}" />
</p:column>
<p:column headerText="#{pvtmsg.email}">
<h:outputText value="#{user.email}" />
</p:column>
<p:column headerText="#{pvtmsg.status}">
<h:outputText value="#{user.enabled ? pvtmsg.enabled : pvtmsg.disabled}" />
</p:column>
<p:column style="width:32px;text-align: center">
<p:commandLink action="editUser.xhtml?faces-redirect=true">
<f:setPropertyActionListener value="#{user.id}" target="#{manageUsers.selectedUser}" />
<f:param name="userId" value="#{manageUsers.selectedUser}" />
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
Its backing bean
package beans;
import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import models.User;
import utils.PropertyHelper;
#Named(value = "manageUsers")
#ViewScoped
public class ManageUsers implements Serializable {
private static final long serialVersionUID = 954672295622776147L;
private List<User> users = null;
private String selectedUser = null;
public ManageUsers() {
try {
PropertyHelper helper = new PropertyHelper();
users = helper.getUsers();
} catch (Exception ex) {
Logger.getLogger(ManageUsers.class.getName()).log(Level.SEVERE, null, ex);
}
}
public List<User> getUsers() {
return users;
}
public String getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(String selectedUser) {
this.selectedUser = selectedUser;
}
}
The second page
<f:metadata>
<f:viewParam name="userId" value="#{editUserBean.userId}" />
</f:metadata>
<h:form id="editUserForm" prependId="false">
<p:growl id="messages" showDetail="true" life="20000"/>
<!--nothing yet-->
</h:form>
Its backing bean
package beans;
import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named(value = "editUserBean")
#ViewScoped
public class EditUserBean implements Serializable {
private static final long serialVersionUID = 543216875622776147L;
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
Your commandLink doesn't make sense here. Typically when you want to navigate with a commandLink, you should do a redirect in your backing bean.
If you want to navigate using outcome, then something like this should work for you:
<h:link outcome="editUser.xhtml">
<f:param name="userId" value="#{user.id}" />
</h:link>
So I found my solution here http://www.oracle.com/technetwork/articles/java/jsf22-1377252.html and, after some time, the last piece that I needed here here http://www.coderanch.com/t/625319/JSF/java/working-viewParam
Your f:viewParams won't be available during the #PostConstruct method call. You should assign a f:viewAction, since you are using JSF 2.2, to handle business processing on GET parameters.
<f:metadata>
<f:viewParam name="userId" value="#{editUserBean.userId}" />
<f:viewAction action="#{editUserBean.processUserId}"/>
</f:metadata>
See also:
Read this if using JSF older than 2.2
JSF bean: call #PostConstruct function after ViewParam is set
I'm using an editable Primefaces p:datatable to show the data to the user. In this datatable, I have a p:column with a h:selectOneMenu, and another one with a p:selectBooleanCheckbox.
I want to check or uncheck and disable or enable the checkbox depending on the value selected in the h:selectOneMenu.
If I only had one h:selectOneMenu and one p:selectBooleanCheckbox, I'd use a p:ajax to attach a listener to the change event, and I'd manipulate the p:selectBooleanCheckbox in this method. But I have a pair of h:selectOneMenu and p:selectBooleanCheckbox per row and I don't know how to do this.
This is what I tried:
<h:form>
<p:dataTable var="appointment" value="#{prescController.appointmentsToday}" editable="true" id="tblAppointments">
<p:ajax event="rowEdit"
listener="#{prescController.onEdit}" update=":messages" />
<p:column sortBy="presc.drug" headerText="Drug">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{appointment.presc.drug.name}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{appointment.presc.drug}"
converter="#{drugConverter}" required="true">
<f:selectItem itemLabel="" noSelectionOption="true" />
<f:selectItems value="#{prescController.drugs}"
var="drug" itemLabel="#{drug.name}" />
<p:ajax update="autoAmount" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="presc.autoAmount" headerText="Auto amount">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="Y"
rendered="#{not empty appointment.presc.drug.rules and appointment.presc.autoAmount}" />
<h:outputText value="N"
rendered="#{empty appointment.presc.drug.rules or not appointment.presc.autoAmount}" />
</f:facet>
<f:facet name="input">
<p:selectBooleanCheckbox id="autoAmount"
value="#{not empty appointment.presc.drug.rules and appointment.presc.autoAmount}"
disabled="#{appointment.presc.drug.name eq 'somethingsomething'}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
The post Retrieving other component's client ID in JSF 2.0 describes how to retrieve ids of other components in a page. In my opinion, the #{p:component('sampleButton')} should find the next component having this ID in the component tree - this should be the same row.
Alternatively, you should be able to rerender the whole row via JSF 2 #{component.parent.clientId} functionality (measure out, how many "parent" steps you need, e.g. #{component.parent.parent.clientId}).
Hope it helps, else just add comments... :-)
I can't imagine why you are unsatisfied with simple update="checkboxId"but what you can try is updating component through widgetVar which you can generate during page render.
Tiny example:
<?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://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Table Example</title>
</h:head>
<h:body>
<h:form prependId="false">
<p:dataTable var="data" value="#{tableBean.data}">
<p:column headerText="Command">
<p:commandButton value="Toggle" actionListener="#{tableBean.toggleSelection(data.id)}"
update="#widgetVar(tableCheckboxComponent_#{data.id})" />
</p:column>
<p:column headerText="Value">
<h:outputText value="#{data.value}" />
</p:column>
<p:column headerText="Selected">
<p:selectBooleanCheckbox widgetVar="tableCheckboxComponent_#{data.id}" value="#{data.selected}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
Backing bean:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TableBean {
private Map<String, MyData> data;
public List<MyData> getData(){
return new ArrayList<MyData>(data.values());
}
public TableBean() {
data = new HashMap<String, MyData>();
for (int i = 0; i<22; i++) {
String id = "id" + Integer.toString(i);
data.put(id, new MyData( id , i));
}
}
public void toggleSelection(String id) {
MyData myData = data.get(id);
myData.setSelected(!myData.isSelected());
}
}
And Data object:
public class MyData {
private String id;
private boolean selected;
private int value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public MyData(String id, int value) {
this.id = id;
this.value = value;
this.selected = false;
}
}
I still don't know why my approach didn't work.
In the end, I added a listener to the p:ajax component to manipulate the SelectBooleanCheckbox in the managed bean
<p:ajax listener="#{prescBean.onDrugSelected}" update="autoAmount" />
public void onDrugSelected(AjaxBehaviorEvent event) {
Drug drug = (Drug) ((UIOutput) event
.getSource()).getValue();
boolean hasRules = drug.getRules().size() > 0;
SelectBooleanCheckbox cbAutoAmount = (SelectBooleanCheckbox) ComponentUtils
.findComponent(FacesContext.getCurrentInstance().getViewRoot(),
"autoAmount");
cbAutoAmount.setDisabled(!hasRules);
cbAutoAmount.setValue(hasRules);
}
i m using datalist in jsf with primefaces , i m facing problem backing bean class field of selected object does not get updated to selected row of datalist ,it is always giving null object. Here is the code
view File :
`<?xml version="1.0"?>`
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
<h:form>
<p:dataList value="#{tableBean.getList()}" var="job" id="cars"
paginator="true" rows="5" effectSpeed="fast"
paginatorTemplate="{PreviousPageLink} {CurrentPageReport} {NextPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5" type="none">
<f:facet name="header">
Applicants List
</f:facet>
<p:column>
<div style="width: 200px">
<h:outputText value="Name:" style="margin-left:10px" />
<h:outputText value="#{job.name}" style="margin-left:10px" />
<br />
<h:outputText value="Applied for:" style="margin-left:10px" />
<h:outputText value="#{job.jobtitle}" style="margin-left:10px" />
<br />
<h:outputText value="Degree:" style="margin-left:10px" />
<h:outputText value="#{job.degree}" style="margin-left:10px" />
<br />
<h:outputText value="Experience:" style="margin-left:10px" />
<h:outputText value="#{job.experience}" style="margin-left:10px" />
<br />
<h:outputText value="Contact:" style="margin-left:10px" />
<h:outputText value="#{job.contact}" style="margin-left:10px" />
<br />
<h:commandLink value="Call for Interview" style="margin-left:10px"></h:commandLink>
</div>
<br/>
<p:commandButton icon="ui-icon-search"
actionListener="#{tableBean.printView}" title="View Detail">
<f:setPropertyActionListener value="#{job}"
target="#{tableBean.selectedJob}" />
</p:commandButton>
<p:separator id="separator" />
</p:column>
</p:dataList>
</h:form>
</h:body>
</f:view>
table bean class:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import DAO.JobApplicationDao;
import DTO.JobApplicationDto;
#ManagedBean
#ViewScoped
public class TableBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public JobApplicationDto selectedJob;
public TableBean() {
}
public List<JobApplicationDto> getList() {
List<JobApplicationDto> joblist = new ArrayList<JobApplicationDto>();
JobApplicationDao dao = new JobApplicationDao();
joblist =dao.getDroppedCv();
return joblist;
}
public JobApplicationDto getSelectedJob() {
return selectedJob;
}
public void setSelectedJob(JobApplicationDto selectedJob) {
this.selectedJob = selectedJob;
}
public void printView(ActionEvent event) {
try{
System.out.print("Selected Person "+getSelectedJob.getName());
}catch(Exception e){
}
}
}
You should use the setPropertyActionListener with action . Listeners are called before your action is invoked. It seems like the setPropertyActionListener is getting called after actionListener.
Change actionListener="#{tableBean.printView}" to action="#{tableBean.printView}"
and method to
public void printView() {
try{
System.out.print("Selected Person "+getSelectedJob.getName());
}catch(Exception e){
}
}
see this for better understanding of what to use ,
http://balusc.blogspot.com/2006/06/communication-in-jsf.html
You can use datatable selection like this
<p:dataList value="#{tableBean.getList()}" selection="#{tableBean.selectedJob}" var="job" id="cars"
paginator="true" rows="5" effectSpeed="fast"
paginatorTemplate="{PreviousPageLink} {CurrentPageReport} {NextPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5" type="none">
I'am new to PrimeFaces. I'am using it to code the front end of a Saas Application. I' am using a primefaces datatable to display a list of customers. I need to sort and filter the values. Also I need to populate another widget when a row is selected on the datatable. Sorting works but filtering and selection don't work. Below are the code snippets of the bean and the faces page. I'am using PrimeFaces 2.2.1 and JSF 2.0.2.
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head></h:head>
<h:body>
<h:form>
<p:growl id="growl" showDetail="true" />
<p:layout fullPage="true">
<!-- Top Tabbed Panel -->
<p:layoutUnit position="top" id="main" width="600" resizable="false">
<center><h3>SAAS Admin Tool</h3></center>
<p:tabView effect="opacity" effectDuration="normal" collapsible="true" >
<p:tab title="Customer">
<!-- Start of customer datatable -->
<p:dataTable var="customer" value="#{customerBean.customers}" paginator="true" selection="#{customerBean.selectedCustomer}"
selectionMode="single" onRowSelectUpdate="custList" onRowSelectComplete="custTest.show()" id="custList" widgetVar="custList">
<f:facet name="header">
List of Customers
<p:outputPanel>
<p:commandButton value="+" type="button" onclick="addCustDlg.show()"/>
</p:outputPanel>
</f:facet>
<p:column sortBy="#{customer.id}" filterBy="#{customer.id}" update=":custList" headerText="ID">
<h:outputText value="#{customer.id}"/>
</p:column>
<p:column sortBy="#{customer.name}" filterBy="#{customer.name}" headerText="NAME" filterMatchMode="contains">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.description}" filterBy="#{customer.description}" headerText="DESCRIPTION">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.description}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.description}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.signupDate}" filterBy="#{customer.signupDate}" headerText="SIGN UP DATE">
<h:outputText value="#{customer.signupDate}"/>
</p:column>
<p:column sortBy="#{customer.validUntil}" filterBy="#{customer.validUntil}" headerText="EXPIRY DATE">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.validUntil}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.validUntil}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.status}" filterBy="#{customer.status}" headerText="STATUS">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.status}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.status}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="CREATION DATE" sortBy="#{customer.creationDate}" filterBy="#{customer.creationDate}">
<h:outputText value="#{customer.creationDate}"/>
</p:column>
<p:column headerText="LAST UPDATE DATE" sortBy="#{customer.lastUpdateDate}" filterBy="#{customer.lastUpdateDate}">
<h:outputText value="#{customer.lastUpdateDate}"/>
</p:column>
<p:column headerText="Options">
<p:rowEditor/>
</p:column>
</p:dataTable>
<!-- End of dataTable (customer datatable) -->
<!-- Customer Details Tabbed Panel-->
<p:tabView effect="opacity" effectDuration="normal" id="custTab" widgetVar="custTab">
<p:tab title="Lines">
lines info..
</p:tab>
<p:tab title="LineCards">
Linecards..
</p:tab>
</p:tabView>
<!-- END of customer details tabbed view -->
</p:tab>
<p:tab title="Deployment">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="software"/>
</h:panelGrid>
</p:tab>
<p:tab title="Maintainence">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="test."/>
</h:panelGrid>
</p:tab>
<p:tab title="Audit Trail">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="Hardware Summary"/>
</h:panelGrid>
</p:tab>
</p:tabView>
</p:layoutUnit>
<!-- DIALOGs -->
<p:dialog header="Add Customer" widgetVar="addCustDlg" id="addCustDlg" resizable="false" width="420" onCloseUpdate="custList">
<h:panelGrid columns="2">
<h:outputLabel value="Name:"/>
<p:inputText value="#{customerBean.newCustomer.name}" required="true"/>
<h:outputLabel value="Description:"/>
<p:inputText value="#{customerBean.newCustomer.description}" required="true"/>
<h:outputLabel value="Sign Up Date:"/>
<p:inputMask value="#{customerBean.signDate}" mask="99/99/2099"/>
<h:outputLabel value="Expiry Date:"/>
<p:inputMask value="#{customerBean.exDate}" mask="99/99/2099"/>
<h:outputLabel value="Status:"/>
<p:inputText value="#{customerBean.newCustomer.status}" required="true"/>
<p:commandButton value="Submit" oncomplete="addCustDlg.hide();" actionListener="#{customerBean.addCustomer}" update=":custList"/>
</h:panelGrid>
</p:dialog>
<p:dialog header="customer info" widgetVar="custTest" id="custTest" closable="true">
<h:outputLabel value="Name: #{customerBean.selectedCustomer.name}"/>
</p:dialog>
<!-- Save and Reset buttons -->
<p:layoutUnit position="bottom" id="buttons" height="75">
<center>
<p:commandButton value="Save Changes" actionListener="#{customerBean.save}" update="growl"/>
<p:commandButton value="Reset" actionListener="#{customerBean.reset}" update="growl"/>
</center>
</p:layoutUnit>
</p:layout>
</h:form>
</h:body>
</html>
The Bean code:
import java.io.Serializable;
import java.sql.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import com.assia.saas.dao.AbstractSearchDAO;
import com.assia.saas.dao.EntityManagerHelper;
import com.assia.saas.entities.Customer;
#ManagedBean(name="customerBean")
#ViewScoped
public class CustomerBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
AbstractSearchDAO<Customer> custDao = new AbstractSearchDAO<Customer>() {
#Override
protected Class<Customer> getEntityClass() {
return Customer.class;
}
#Override
protected Customer getEntityReference(Customer entity) {
return getEntityManager().getReference(Customer.class, entity.getId());
}
};
List<Customer> customers = new ArrayList<Customer>();
private Customer selectedCustomer = new Customer();
private Customer newCustomer;
private String signDate;
private String exDate;
/**
* #return the signDate
*/
public String getSignDate() {
return signDate;
}
/**
* #param signDate the signDate to set
*/
public void setSignDate(String signDate) {
this.signDate = signDate;
}
/**
* #return the exDate
*/
public String getExDate() {
return exDate;
}
/**
* #param exDate the exDate to set
*/
public void setExDate(String exDate) {
this.exDate = exDate;
}
/**
* #return the newCustomer
*/
public Customer getNewCustomer() {
return newCustomer;
}
/**
* #param newCustomer the newCustomer to set
*/
public void setNewCustomer(Customer newCustomer) {
this.newCustomer = newCustomer;
}
public CustomerBean(){
customers = custDao.findAll(null);
newCustomer = new Customer();
}
public void save(){
//TODO: CODE METHOD
}
public void reset(){
//TODO: Code Method
}
/**
* #return the customers
*/
public List<Customer> getCustomers() {
return customers;
}
/**
* #param customers the customers to set
*/
public void setCustomers(List<Customer> customers) {
this.customers = customers;
}
/**
* #param selectedCustomer the selectedCustomer to set
*/
public void setSelectedCustomer(Customer selectedCustomer) {
this.selectedCustomer = selectedCustomer;
}
/**
* #return the selectedCustomer
*/
public Customer getSelectedCustomer() {
return selectedCustomer;
}
public void addCustomer(ActionEvent event) throws ParseException{
Date date = new Date(Calendar.getInstance().getTimeInMillis());
newCustomer.setCreationDate(date);
newCustomer.setLastUpdateDate(date);
DateFormat formatter;
formatter = new SimpleDateFormat("MM/dd/yyyy");
java.sql.Date sqlDate = new java.sql.Date(formatter.parse(signDate).getTime());
newCustomer.setSignupDate(sqlDate);
sqlDate = new java.sql.Date(formatter.parse(exDate).getTime());
newCustomer.setValidUntil(sqlDate);
EntityManagerHelper.beginTransaction();
custDao.save(newCustomer);
EntityManagerHelper.commit();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Success", "New Customer Added"));
}
}
The code is not populating the "selectedCustomer" object in the bean.
What i Undestand from your question is you want create an Editable DataTable. As you are using dataTable attribute selectionMode="Single" which seems everything right for me. I cant say what went wrong with it as it involved many other complexities. But you can achieve the samething (populating selectedCustomer In Backing bean)
Solution1:
you implement Below listener
rowEditListener="#{customerBean.listenerInBackingBean}"
And In backing bean..........
public void listenerInBackingBean(org.primefaces.event.RowEditEvent ev) {
Customer selectedCustomer = (Customer) ev.getObject();
//write Logic to Store Customer in Database
}
Solution 2:
<p:commandButton >
<f:setPropertyActionListener value="#{customer}" target="#{customerBean.selectedCustomer}" />
</p:commandButton>
Here selectedCustomer is instance of type Customer.