Im trying to send data from one jsf page to another, but without success.
firstPage.xhtml
<h:form>
<p:dataTable id="dataList" value="#{firstBean.dataList}" var="data">
<p:column>
<f:facet name="header">Column 1</f:facet>
#{data.column1.id}
</p:column>
<p:column>
<f:facet name="header" >Column 2</f:facet>
#{data.colum2.name}
</p:column>
<p:column>
<f:facet name="header" >Detail Row</f:facet>
<!-- I need this button send me to another page where i will detail information about an certain id -->
<h:commandButton value="Detalhar" action="#{firstBean.someMethod}">
<f:param name="dataId" value="#{data.column1.id}"/>
</h:commandButton>
</p:column>
</p:dataTable>
</h:form>
First Bean
#ManagedBean
#ViewScoped
public class FirstBean implements Serializable{
private static final long serialVersionUID = 1L;
//list with some data
private List<Data> dataList; //getter setter
#EJB
MyDataManager manager;
#PostConstruct
public void init() {
dataList = manager.getDataList();
}
public void someMethod() throws IOException {
//do something
FacesContext.getCurrentInstance().getExternalContext().redirect("secondPage.xhtml");
}
}
secondPage.xhtml
<h:body>
<f:metadata>
<f:viewParam name="dataId" value="#{secondBean.dataDetailId}" />
<f:viewAction action="#{secondBean.init}" />
</f:metadata>
<p:dataTable value="#{secondBean.dataDetailList}" var="dataDetail">
<p:column>
<f:facet name="header">Data Detail 1</f:facet>
#{dataDetail.data1}
</p:column>
<p:column>
<f:facet name="header">Data Detail 2</f:facet>
#{dataDetail.data2}
</p:column>
<p:column>
<f:facet name="header">Data Detail 3</f:facet>
#{dataDetail.data3}
</p:column>
</p:dataTable>
</h:body>
Second Bean
#ManagedBean
#ViewScoped
public class CarteiraDetalheBean implements Serializable{
private static final long serialVersionUID = 1L;
private Integer dataId; //getter setter
private List<DataDetail> dataDetailList; //getter setter
#EJB
MyDataManager manager;
#PostConstruct
public void init() {
dataDetailList = manager.getDataDetail(dataId);
}
}
When i use:
<f:viewAction action="#{secondBean.init}" />
I gotthe message: The metadata component needs to be nested within a f:metadata tag. Suggestion: enclose the necessary components within
and when i use:
<f:event type="preRenderView" listener="#{secondBean.init()}" />
i got a null pointer exception in line:
dataDetailList = manager.getDataDetail(dataId);
What im doing wrong?
Related
I implemented the <p:rowExpansion> from PF in my HTML, as seen below.
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column headerText="Content 1" sortBy="#{portview.port_comment}">
<h:outputText value="#{contentbean.content1}" />
</p:column>
<p:rowExpansion>
<p:panelGrid columns="2" columnClasses="label,value" style="width:50%">
<h:outputText value="Label:" />
<h:outputText value="#{portview.port_comment}" />
</p:panelGrid>
</p:rowExpansion>
Yet, the data shown in the expansion does not fit the row it was issued from and in the PF website I can't find any clues on how to solve this.
Q: What should I do here?
UPDATE:
I use version 8.0 of Primefaces. The outcome looks like this...
The data in the expansion shows just any value from the view.
Here's my bean behind the html...
#Named(value = "vb")
#ViewScoped
public class ViewBean implements Serializable {
#Inject
private ViewHandler vh;
#PostConstruct
public void init() {
}
public List<PortView> getPVList() {
return vh.getPortViewList();
}
And the ViewHandler looks like this...
#Stateless
public class ViewHandler {
public List<PortView> getPortViewList() {
List<PortView> pvlist = em.createQuery("SELECT v FROM PortView v", PortView.class).getResultList();
return pvlist;
}
First of all I know some other similar questions about my title, but My issue is a little bit different... When I try to initialize LazyDataModel in my #ViewScoped Bean it works fine until I click the actionButton on my page. When My Bean is created, its #PostConstruct method works as expected and LazyDataModel filled up in that method then datatable populated well. But when ajax called by actionButton in my page then entire bean recreated and #PostConstruct method called again, with that LazyDataModel value changing to null. Because of that, my page is crashing. In another scenario I was using rowSelect event in my datatable instead of actionButton with method which has a SelectEvent parameter. In SelectEvent parameter object field of it was null and I was getting NullPointerException. These are the scenarios... As result I guess when I use LazyDataModel in my #ViewScoped bean It calls PostConstruct again and my datamodel returns null for my SelectEvent method.
This is my ViewScoped PostConstruct method
#ManagedBean (name = "myEctrInboxBB")
#ViewScoped
public class MyEContractInboxBackingBean implements Serializable {
private static final long serialVersionUID = 2399679621562918360L;
private static final Logger logger = LogManager.getLogger(MyEContractInboxBackingBean.class);
#ManagedProperty("#{ectrDomainService}")
EContractDomainService ectrDomainService;
#ManagedProperty("#{eContractUtil}")
EContractUtilBean eContractUtil;
#ManagedProperty("#{ectrApproveController}")
EContractApproveControllerBean ectrApproveController;
private EContractInboxItem selectedInboxRow;
private LazyEContractInboxItemModel lazyEcontractInboxItem;
private List<EContractInboxItem> inboxItems = new ArrayList<EContractInboxItem>();
private List<EContractInboxItem> filteredInboxItems = new ArrayList<EContractInboxItem>();
#PostConstruct
public void init() {
User portalUser = getUser();
List<String> userRoles = fetchUserRoles(portalUser);
List<String> userSmCodes = fetchUserSmCodes(userRoles, portalUser);
lazyEcontractInboxItem = new LazyEContractInboxItemModel(ectrDomainService, eContractUtil, userRoles, userSmCodes);
}
public void onRowSelect(SelectEvent selectEvent) {
logger.info("**************************" + selectEvent);
}
public void openSelectedJob(EContractInboxItem item) {
ectrApproveController.openEContractInfoPage(item.getProcessInstanceId());
}
LazyDataModel
public class LazyEContractInboxItemModel extends LazyDataModel<EContractInboxItem>{
List<EContractInboxItem> inboxItems = new ArrayList<EContractInboxItem>();
List<Task> taskList = new ArrayList<Task>();
EContractDomainService ectrDomainService;
EContractUtilBean ectrUtilBean;
List<String> userRoles = new ArrayList<String>();
List<String> userSmCodes = new ArrayList<String>();
public LazyEContractInboxItemModel(EContractDomainService ectrDomainService, EContractUtilBean utilBean, List<String> roles,
List<String> smCodes) {
userRoles.addAll(roles);
userSmCodes.addAll(smCodes);
ectrUtilBean = utilBean;
this.ectrDomainService = ectrDomainService;
}
public List<EContractInboxItem> getInboxItems() {
return inboxItems;
}
public void setInboxItems(List<EContractInboxItem> inboxItems) {
this.inboxItems = inboxItems;
}
#Override
public List<EContractInboxItem> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
taskList = ectrDomainService.findTaskListAssignedToUserByUser(userRoles, userSmCodes);
inboxItems.clear();
inboxItems.addAll(ectrUtilBean.retrieveInboxItems(taskList));
setRowCount(inboxItems.size());
return inboxItems;
}
#Override
public List<EContractInboxItem> load(int first, int pageSize, List<SortMeta> multiSortMeta,
Map<String, Object> filters) {
taskList = ectrDomainService.findTaskListAssignedToUserByUser(userRoles, userSmCodes);
inboxItems.clear();
inboxItems.addAll(ectrUtilBean.retrieveInboxItems(taskList));
setRowCount(inboxItems.size());
return inboxItems;
}
#Override
public Object getRowKey(EContractInboxItem object) {
return object.getProcessInstanceId();
}
#Override
public EContractInboxItem getRowData() {
return super.getRowData();
}
#Override
public EContractInboxItem getRowData(String rowKey) {
for (EContractInboxItem eContractInboxItem : inboxItems) {
if (rowKey.equals(eContractInboxItem.getProcessInstanceId()))
return eContractInboxItem;
}
return null;
}
getters and setters
xhtml page with actionButton
<?xml version="1.0"?>
<ui:composition
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"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:form
id="eContractWaitingApprovalForm"
prependId="false"
enctype="multipart/form-data">
<p:messages id="topmsgForEcontractWaitingApproval" />
<div class="ui-grid ui-grid-responsive">
<p:dataTable
id="waitingEcontracts"
widgetVar="waitingEcontracts"
styleClass="grid-sm-bottom"
rows="20"
resizableColumns="true"
resizeMode="expand"
paginator="true"
lazy="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,50,100,200"
value="#{myEctrInboxBB.lazyEcontractInboxItem}"
var="item">
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.no']}">
<h:outputText value="#{item.eContract.eContractCode}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.subject']}">
<h:outputText value="#{item.eContract.eContractSubject}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.date']}">
<h:outputText value="#{item.eContract.eContractDate}">
<f:convertDateTime
type="date"
pattern="dd-MM-yyyy" />
</h:outputText>
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.name']}">
<h:outputText value="#{item.agencyName}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.type']}">
<h:outputText value="#{item.agencyType}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.sales.manager']}">
<h:outputText
value="#{myEctrInboxBB.findSalesOfficeBySmCode(item.agencySM)}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.status']}">
<h:outputText
value="#{item.eContract.eContractStatus eq 'INPROGRESS' ? i18n['e-contract.dt.waiting.inprogress'] : item.eContract.eContractStatus}" />
</p:column>
<p:column styleClass="center-column">
<p:commandButton
process="#this"
icon="ui-icon-search"
value="#{i18n['e-contract.dt.waiting.see.detail']}"
action="#{myEctrInboxBB.openSelectedJob(item)}" />
</p:column>
</p:dataTable>
</div>
</h:form>
xhtml page with rowSelect
<?xml version="1.0"?>
<ui:composition
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"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:form
id="eContractWaitingApprovalForm"
prependId="false"
enctype="multipart/form-data">
<p:messages id="topmsgForEcontractWaitingApproval" />
<div class="ui-grid ui-grid-responsive">
<p:dataTable
id="waitingEcontracts"
widgetVar="waitingEcontracts"
styleClass="grid-sm-bottom"
rows="20"
resizableColumns="true"
resizeMode="expand"
paginator="true"
lazy="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,50,100,200"
value="#{myEctrInboxBB.lazyEcontractInboxItem}"
var="item"
selection="#{myEctrInboxBB.selectedInboxRow}"
selectionMode="single"
rowKey="#{item.processInstanceId}">
<p:ajax event="rowSelect" listener="#{myEctrInboxBB.onRowSelect}"/>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.no']}">
<h:outputText value="#{item.eContract.eContractCode}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.subject']}">
<h:outputText value="#{item.eContract.eContractSubject}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.date']}">
<h:outputText value="#{item.eContract.eContractDate}">
<f:convertDateTime
type="date"
pattern="dd-MM-yyyy" />
</h:outputText>
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.name']}">
<h:outputText value="#{item.agencyName}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.type']}">
<h:outputText value="#{item.agencyType}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.sales.manager']}">
<h:outputText
value="#{myEctrInboxBB.findSalesOfficeBySmCode(item.agencySM)}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.status']}">
<h:outputText
value="#{item.eContract.eContractStatus eq 'INPROGRESS' ? i18n['e-contract.dt.waiting.inprogress'] : item.eContract.eContractStatus}" />
</p:column>
</p:dataTable>
</div>
</h:form>
When I clicked a row of Datatable selectEvent.getObject() --> NULL always with LazyDataModel.
A big important information: These all situations happens in WebLogic 10.3.6.0 and works on TomCat like charm (even with LazyDataModel).
My Development environment: JSF 2.0, Primefaces 5.2, Liferay 6.2.3 ga4 with TomCat 7.04.
Testing environment: Same all except WebLogic 10.3.6.0 (Problem only occurs on here)
I really appreciate if someone could help me... Thanks in advance!!!
EDIT:
#ManagedBean (name = "myEctrInboxBB")
#ViewScoped
public class MyEContractInboxBackingBean implements Serializable {
private static final long serialVersionUID = 2399679621562918360L;
private static final Logger logger = LogManager.getLogger(MyEContractInboxBackingBean.class);
#ManagedProperty("#{ectrDomainService}")
private transient EContractDomainService ectrDomainService;
#ManagedProperty("#{eContractUtil}")
private EContractUtilBean eContractUtil;
#ManagedProperty("#{ectrApproveController}")
private EContractApproveControllerBean ectrApproveController;
private EContractInboxItem selectedInboxRow;
private LazyEContractInboxItemModel lazyEcontractInboxItem;
#PostConstruct
public void init() {
User portalUser = getUser();
List<String> userRoles = fetchUserRoles(portalUser);
List<String> userSmCodes = fetchUserSmCodes(userRoles, portalUser);
lazyEcontractInboxItem = new LazyEContractInboxItemModel(userRoles, userSmCodes);
}
We can access Spring Beans like that:
public EContractProcessService geteContractProcessService() {
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
return (EContractProcessService) FacesContext.getCurrentInstance().getApplication()
.getELResolver().getValue(elContext, null, "eContractProcessService");
}
I have a problem with primefaces datatable. I'm getting the data from my database and it's saved in a list. That's works great! But the datatable just displays one column instead of four and this column is copied in every row.
<h:form id="userslistform">
<p:dataTable id="userlist" var="users" value="#{userBean.usersList}"
rowKey="#{userBean.username}">
<p:column headerText="ID">
<h:outputText value="#{userBean.id}" />
</p:column>
<p:column headerText="Username">
<h:outputText value="#{userBean.username}" />
</p:column>
<p:column headerText="Firstname">
<h:outputText value="#{userBean.firstname}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{userBean.surname}" />
</p:column>
</p:dataTable>
</h:form>
Bean:
#Named
#SessionScoped
#ManagedBean(name = "userBean")
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private String password;
private String firstname;
private String surname;
private Long id;
private String email;
private Long treeId;
private Boolean isadmin;
private List<User> usersList;
private User selectedUser;
private UserDataQuery query = new UserDataQuery();
//getter and setters of every attribute
...
#PostConstruct
public void init() {
usersList = query.getAllUsers();
}
}
DAO:
public class UserDataQuery {
private EntityManagerFactory enf;
private EntityManager em;
public UserDataQuery() {
enf = Persistence.createEntityManagerFactory("xxxx");
em = enf.createEntityManager();
em.getTransaction().begin();
}
public List<User> getAllUsers() {
List<User> usersList = em.createNamedQuery("User.findAll", User.class)
.getResultList();
return usersList;
}
...
}
You need to use value from var inside your table, to display the data
<h:form id="userslistform">
<p:dataTable id="userlist" var="users" value="#{userBean.usersList}"
rowKey="#{userBean.username}">
<p:column headerText="ID">
<h:outputText value="#{users.id}" />
</p:column>
<p:column headerText="Username">
<h:outputText value="#{users.username}" />
</p:column>
<p:column headerText="Firstname">
<h:outputText value="#{users.firstname}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{users.surname}" />
</p:column>
</p:dataTable>
</h:form>
var value represents a reference to current row, at the time the table is rendered. With #{userBean.<attribute>} you were always displaying values that were fixed. And, now you don't need those attributes in the bean itself, just the list (unless, of course, you need them for another purpose).
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
For example,
<p:dataTable var="price" value="#{testManagedBean.price}" rowIndexVar="rowIndex">
<p:column headerText="Index">
<h:outputText value="#{rowIndex+1}"/>
</p:column>
<p:column headerText="Price" style="text-align: right;">
<h:outputText value="#{price}"/>
<f:facet name="footer">
<c:set var="total" value="${total+price}"/>
<h:outputText value="#{total}"/>
</f:facet>
</p:column>
</p:dataTable>
The managed bean:
#ManagedBean
#ViewScoped
public final class TestManagedBean implements Serializable
{
private List<BigDecimal>price;
private static final long serialVersionUID = 1L;
#PostConstruct
public void init()
{
price=new ArrayList<>();
price.add(new BigDecimal(50));
price.add(new BigDecimal(100));
price.add(new BigDecimal(150));
price.add(new BigDecimal(200));
price.add(new BigDecimal(250));
price.add(new BigDecimal(300));
}
public List<BigDecimal> getPrice() {
return price;
}
}
The total of list of items is to be displayed on the footer.
Is this possible to do this summation using JSTL or otherwise without having a method that does this summation in the backing bean itself?
Currently the operation with JSTL <c:set> yields 0 on the footer of the associated column.
Something like this works for me:
<c:set var="total" value="0"/>
<c:forEach items="#{testManagedBean.price}" var="t">
<c:set var="total" value="#{total + t}"/>
</c:forEach>
<h:outputText value="#{total}"/>
I will not reject the idea it might be optimizable :-)