Paginator of <p:dataTable> doesn't show the data - java

I'm new in this community, but I really need help!
I'm programming a application which gonna run in Desktop, with Java, and online, with Java Web, using Hibernate 4.3, without JPA, and Primefaces 8.2.
My issue is, I have a page with a dataTable, this dataTable contains a button on each register to open a dialog with more information of this register.
Inside this dialog i have another dataTable with another button inside each register.
Here I have two issues.
First, when user clicks on the button in the first dialog, the second dialog appears but, it just ignore the ActionListener.
Second, on the first dialog, when user clicks to go to other page of dataTable, or just increase the number of rows, the data disappear! If you close and reopen the dialog, it open in the page you clicked before and the data will be there.
I'll post the principal code of the problem, the github link and a video to make it easy to figure out the problem.
Bean.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;
import com.sysnutriweb.dao.AlimentoXDietaDAO;
import com.sysnutriweb.dao.DietaDAO;
import com.sysnutriweb.dataModel.AlimentoDataModel;
import com.sysnutriweb.domain.Alimento;
import com.sysnutriweb.domain.AlimentoXDieta;
import com.sysnutriweb.domain.Dieta;
#ManagedBean(name = "MBDiet")
#SessionScoped
public class DietaBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Dieta> listDiets;
private Dieta diet = new Dieta();
private DietaDAO dDao;
private LazyDataModel<AlimentoXDieta> foods;
private Alimento food = new Alimento();
#PostConstruct
public void begin() {
dDao = new DietaDAO();
listDiets = dDao.loadAll();
}
public void getDietSelected(ActionEvent e) {
diet = (Dieta) e.getComponent().getAttributes().get("selectedDiet");
List<AlimentoXDieta> foods = new ArrayList<>();
List<AlimentoXDieta> axd = new AlimentoXDietaDAO().loadAll();
for (int i = 0; i < axd.size(); i++) {
if (axd.get(i).getDietId().getId() == diet.getId())
foods.add(axd.get(i));
}
this.foods = new AlimentoDataModel(foods);
}
public void getFoodSelected(ActionEvent e) {
food = (Alimento) e.getComponent().getAttributes().get("selectedFood");
}
// Getters and Setters
Index.xhtml
<f:metadata>
<f:param name="selectedDiet" value="#{MBDiet.diet}" />
</f:metadata>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Menu de dietas SysNutri</title>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" resizable="false"
closable="false" collapsible="false">
<center>
<h:outputText value="Sistema de Nutrição SYSNUTRIWEB" />
</center>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:form id="formTable">
<p:dataTable emptyMessage="Nenhum dado cadastrado!"
paginator="false" id="tbAllDiets" value="#{MBDiet.listDiets}"
var="diet">
<p:column headerText="Nome" id="nome">
<p:outputLabel value="#{diet.nomeDieta}" />
</p:column>
<p:column headerText="Descrição da dieta" id="descricao">
<p:outputLabel value="#{diet.descricaoDieta}" />
</p:column>
<p:column headerText="Ações" id="acoes" width="10%">
<center>
<p:commandButton immediate="false" icon="ui-icon-info"
id="btnInfo" update=":formInfoTable"
actionListener="#{MBDiet.getDietSelected}"
oncomplete="PF('dlgFoods').show()">
<f:attribute name="selectedDiet" value="#{diet}" />
</p:commandButton>
<p:tooltip id="toolTipBtnInfo" for="btnInfo"
value="Clique para ver os alimentos presentes nesta dieta"
position="top" />
</center>
</p:column>
</p:dataTable>
</h:form>
</p:layoutUnit>
</p:layout>
<!-- Dialogs -->
<!-- Diet info -->
<p:dialog header="Alimentos da dieta selecionada" widgetVar="dlgFoods"
closable="true" modal="true" showEffect="explode" id="dialogFoods"
resizable="false" draggable="false" appendTo="#(body)">
<h:form id="formInfoTable">
<center>
<p:outputLabel id="diet" value="Dieta #{MBDiet.diet.nomeDieta}"
style="font-weight: bold;" />
</center>
<p:dataTable emptyMessage="Nenhum dado cadastrado!" paginator="true"
id="tbFoodsDiet" value="#{MBDiet.foods}" var="food" rows="4"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="4,5,6,7,8,9,10" lazy="true">
<p:column headerText="Nome" id="nome" width="10px">
<p:outputLabel value="#{food.foodId.nome}" />
</p:column>
<p:column headerText="Hora para consumir" id="descricao" width="40%">
<p:outputLabel value="#{food.hora}" />
</p:column>
<p:column headerText="Ações" id="acoes" width="10%">
<center>
<p:commandButton immediate="false" icon="ui-icon-info"
id="btnInfo" update=":formInfo"
actionListener="#{MBDiet.getFoodSelected}"
oncomplete="PF('dlgFoodInfo').show()">
<f:attribute name="selectedFood" value="#{food}" />
</p:commandButton>
<p:tooltip id="toolTipBtnInfo" for="btnInfo"
value="Clique para ver os alimentos presentes nesta dieta"
position="top" />
</center>
</p:column>
</p:dataTable>
</h:form>
</p:dialog>
<!-- Second Dialog -->
Github: https://github.com/SakamotoLfe/SysNutriWebV0
Vdieo: Coming soon.

Related

Primefaces datatable change item with wrong id (onrowedit) when I have a separate method for searching the datatable [duplicate]

This question already has an answer here:
How and when should I load the model from database for JSF dataTable
(1 answer)
Closed 1 year ago.
I have a bean that brings the list of products from the database, I can change it in onRowEdit normally, but when I do a search for the part method in the beanProd.searchProd () form it populates the datatable with related products and when I change some of them event.getObject () takes the object with an incorrect id and update incorrect product. Please HELP-ME
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="a.css" library="css" />
</h:head>
<h:body>
<div id="go">
<p:panel id="basic" header="Adicionar Produto"
style="margin-bottom:20px; width:400px">
<p:panelGrid columns="4" style="margin:10px 0"/>
<h:form id="form1" >
<p:outputLabel value="Marca:" />
<td> </td>
<p:inputText id="marcacomp" value="#{beanProd.marcaProd}"
size="25" required="true" requiredMessage="#{beanMsgs.campovazio}" />
<p:message for="marcacomp" />
<br/>
<p:outputLabel value="Nome:" />
<td> </td>
<p:inputText id="nome" value="#{beanProd.nomeProd}"
size="25" required="true" requiredMessage="#{beanMsgs.campovazio}" />
<p:message for="nome" />
<br/>
<p:outputLabel value="Tamanho:" />
<td></td>
<p:inputText id="tamanho" value="#{beanProd.tamanhoProd}"
size="25" required="true" requiredMessage="#{beanMsgs.campovazio}"/>
<p:message for="tamanho" />
<br/>
<p:commandButton id="button" value="Adicionar" ajax="false"
actionListener="#{beanProd.addUser()}" update="datatable"/>
<p:messages id="messages" showDetail="true" closable="true" />
<td></td>
<td></td>
<td></td>
<br/>
</h:form>
</p:panel>
<p:panel id="basic5" header="Buscar Produtos"
style="margin-bottom:20px; width:380px">
<p:panelGrid columns="1" />
<h:form id="form10">
<p:outputLabel value="Digite a busca:" />
<br></br>
<p:inputText id="buscaprod" value="#{beanProd.busca}"
size="25" requiredMessage="#{beanMsgs.campovazio}" />
<p:commandButton id="button3" value="Buscar" ajax="false"
actionListener="#{beanProd.searchProd()}" update="datatable" />
</h:form>
</p:panel>
<h:form>
<p:commandButton id="button5" value="INVERTER TODOS MOSTRAR" ajax="false"
actionListener="#{beanProd.alterarTodos()}" update="datatable" />
</h:form>
</div>
<div id="direita">
<h:form id="form3">
<p:dataTable id="datatable" value="#{beanProd.produtos}" var="p"
editable="true" sortOrder="ascending" sortBy="#{p.id}"
paginator="true" rows="10">
<f:facet name="header">
Lista de Produtos
</f:facet>
<p:ajax event="rowEdit" listener="#{beanProd.onRowEdit}" update="datatable"/>
<p:ajax event="rowEditCancel" listener="#{beanProd.onRowCancel}" update="datatable"/>
<p:column headerText="Marca"
style="width:70px; text-align: center;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{p.marcaProd}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput2" value="#{p.marcaProd}"
style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Nome"
style="width:110px; text-align: center;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{p.nomeProd}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput3" value="#{p.nomeProd}"
style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Tamanho"
style="width:70px; text-align: center;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{p.tamanhoProd}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput5" value="#{p.tamanhoProd}"
style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Mostrar"
style="width:50px; text-align: center;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="Não" rendered="#{p.mostrar == 0}" />
<h:outputText value="Sim" rendered="#{p.mostrar == 1}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu id="mastrar2"
value="#{beanProd.mostrar2}"
style="height:30px; width:70px" required="false">
<f:param name="mostrar2" value="#{beanProd.mostrar2}" />
<f:selectItem itemLabel="Sim" itemValue="Sim" />
<f:selectItem itemLabel="Nao" itemValue="Nao" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Acao" style="width:30px; text-align: center;">
<p:rowEditor editTitle="Editar" saveTitle="Salvar"
cancelTitle="Cancelar" />
<h:outputLabel id="editRow2">
<p:commandButton id="button" jax="false"
icon="ui-icon-circle-close" title="Excluir"
action="#{beanProd.deleteFromDB(p)}" update="datatable"
process="#this">
<p:confirm header="Confirmação" message="Tem certeza que deseja excluir este usuario?"
icon="pi pi-exclamation-triangle" />
</p:commandButton>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="SIM" type="button"
styleClass="ui-confirmdialog-yes" />
<p:commandButton value="NÃO" type="button"
styleClass="ui-confirmdialog-no" />
</p:confirmDialog>
<p:message for="button" />
</h:outputLabel>
<p:tooltip for="editRow2" value="Excluir" showEffect="fade"
hideEffect="fade" />
</p:column>
</p:dataTable>
</h:form>
</div>
</h:body>
</html>
package Bean;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
import DAO.DaoFactory;
import DAO.PredictDAO;
import Model.Produto;
import Model.Usuario;
#ManagedBean(name="beanProd")
#RequestScoped
public class BeanProd implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Produto produto = new Produto();
private ArrayList<Produto> produtos;
private String marcaProd;
private String nomeProd;
private String tamanhoProd;
private String busca;
private String mostrar2;
private boolean ativo;
public BeanProd() {
}
#PostConstruct
public void init() {
buscarTodosProd();
}
public ArrayList<Produto> buscarTodosProd() {
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
produtos = dao.buscaProdutos();
factory.fecharConexao();
return produtos;
}
public ArrayList<Produto> searchProd() {
produtos.clear();
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
produtos = dao.buscarUmProduto(busca);
System.out.println(busca);
factory.fecharConexao();
return produtos;
}
public ArrayList<Produto> alterarTodos() {
produtos.clear();
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
produtos = dao.alterarTodosProdutos();
factory.fecharConexao();
return produtos;
}
public void addUser() {
Produto produto = new Produto();
produto.setMarcaProd(marcaProd);
produto.setNomeProd(nomeProd);
produto.setTamanhoProd(tamanhoProd);
produto.setMostrar(1);
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
dao.adicionarProduto(produto);
factory.fecharConexao();
produtos.add(produto);
marcaProd = "";
nomeProd = "";
tamanhoProd = "";
}
public void deleteFromDB(Produto produto) {
// FacesContext context = FacesContext.getCurrentInstance();
int id;
// int id = (Integer) event.getComponent().getAttributes().get("id2");
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
// id =
// Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("idhidden"));
try {
// Map m = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
// System.out.println(m.toString());
dao.excluirProduto(produto.getId());
produtos.remove(produto);
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage("Produto Excluido com Sucesso!"));
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
factory.fecharConexao();
}
public void onRowEdit(RowEditEvent<Produto> event) {
Produto promocao2 = new Produto();
promocao2 = (Produto) event.getObject();
System.out.println(promocao2.getId());
DaoFactory factory = new DaoFactory();
factory.abrirConexao();
PredictDAO dao = factory.criarPredictDAO();
dao.atualizarProduto(promocao2);
factory.fecharConexao();
}
public void onRowCancel(RowEditEvent event) {
System.out.println("Chamou onRowCancel!" + event.toString());
FacesMessage msg = new FacesMessage("Edit Cancelled", "" + ((Produto) event.getObject()).getId());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public boolean isAtivo() {
return ativo;
}
public void setAtivo(boolean ativo) {
this.ativo = ativo;
}
public Produto getProduto() {
return produto;
}
public void setProduto(Produto produto) {
this.produto = produto;
}
public ArrayList<Produto> getProdutos() {
return produtos;
}
public void setProdutos(ArrayList<Produto> produtos) {
this.produtos = produtos;
}
public String getMarcaProd() {
return marcaProd;
}
public void setMarcaProd(String marcaProd) {
this.marcaProd = marcaProd;
}
public String getNomeProd() {
return nomeProd;
}
public void setNomeProd(String nomeProd) {
this.nomeProd = nomeProd;
}
public String getTamanhoProd() {
return tamanhoProd;
}
public void setTamanhoProd(String tamanhoProd) {
this.tamanhoProd = tamanhoProd;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String getBusca() {
return busca;
}
public void setBusca(String busca) {
this.busca = busca;
}
public String getMostrar2() {
return mostrar2;
}
public void setMostrar2(String mostrar2) {
this.mostrar2 = mostrar2;
}
#Override
public String toString() {
return "BeanProd [produto=" + produto + ", produtos=" + produtos + ", marcaProd=" + marcaProd + ", nomeProd="
+ nomeProd + ", tamanhoProd=" + tamanhoProd + ", ativo=" + ativo + "]";
}
}
sorry for lack of details, it's my first post here, let's go to the details examples
all produtcts in datatable
Here are the products from the database that populate the datatable init () method with #PostConstruct annotation
When I search the form on the left with the word CREME he calls the searchProd method q populates a datatable with products that contain the word CREME
search form populate datatable search string
as you can see the datatable populated only with products containing the word CREAM
before the search I can change the product directly in the datatable normally it changes the product correctly in the database but when I do the search for a product that contains a certain word and I try to change it in the datatable it changes the product with the wrong id see before:
before
after
as you can see he should change the product with id 14 and he changes the product with id 12
wrong product changed
So, what do you think is the problem here?
Is there any way to make the change in the row along with some search filter?
I'm using JSF 2.2 and Primefaces 8.0
Sorry for my bad english.
This may happen if one of your methods updates the products list, but doesn't update the form (the view).
Start your app in the debug mode, and put a breakpoint on the setter of #{beanProd.produtos}, and find when your list is updated.

Primefaces datatable filtering mode not working

following is my question:
I have a simple piece of code. The Primeface datatable holds the records and should be filtering. But when i tip some letters into a search field, the datatable is shown the "no records found" message. Why?
Here's my code:
<ui:define name="content">
<h:form>
<h:panelGrid columns="1">
<p:dataTable value="#{mainBean.liste}"
var="daten"
rows="6"
emptyMessage="Keine Daten bisher Erfasst"
widgetVar="erfasstTabelle"
paginator="true" resizableColumns="true" paginatorPosition="bottom"
paginatorTemplate=" {CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} Springe zu Seite: {JumpToPageDropdown}"
currentPageReportTemplate="{startRecord} - {endRecord} von {totalRecords}, Seite: {currentPage}/{totalPages})"
rowsPerPageTemplate="5,10,15" filteredValue="#{mainBean.gefiltert}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Alle Felder durchsuchen" />
<p:inputText id="globalFilter" onkeyup="PF('erfasstTabelle').filter()" style="width:150px" placeholder="Suchbegriff"/>
</p:outputPanel>
</f:facet>
<p:column headerText="AVS ID" filterMatchMode="equals" filterBy="#{daten.nummer}">
<h:outputText value="#{daten.nummer}" />
</p:column>
<p:column headerText="Rechtsform">
<h:outputText value="#{daten.rechtsform}" />
</p:column>
<p:column headerText="Erfasser" filterMatchMode="exact" filterBy="#{daten.erfasser}">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('erfasstTabelle').filter()" >
<f:selectItem itemLabel="Erfasser" itemValue="#{null}" noSelectionOption="true" />
<f:selectItems value="#{mainBean.erfasser}" />
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{daten.erfasser}" />
</p:column>
<p:column headerText="Datum" >
<h:outputText value="#{daten.datum}" />
</p:column>
</p:dataTable>
</h:panelGrid>
</h:form>
</ui:define>
And my Bean code:
package de.avs.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import de.avs.entity.Erfasst;
import de.avs.entity.ErfasstDAO;
#ManagedBean
#ViewScoped
public class MainBean implements Serializable{
private static final long serialVersionUID = 1L;
private ErfasstDAO erfasstDAO;
private List<Erfasst> liste;
private List<Erfasst> gefiltert;
private List<String> erfasser;
#PostConstruct
private void init(){
erfasstDAO = new ErfasstDAO();
erfasser = new ArrayList<>();
erfasser.add("Benjamin");
erfasser.add("Uwe");
erfasser.add("Rolf");
liste = erfasstDAO.alleEintraege();
}
public List<Erfasst> getListe() {
return liste;
}
public List<Erfasst> getGefiltert() {
return gefiltert;
}
public void setGefiltert(List<Erfasst> gefiltert) {
this.gefiltert = gefiltert;
}
public List<String> getErfasser() {
return erfasser;
}
public void setErfasser(List<String> erfasser) {
this.erfasser = erfasser;
}
}

javax.el.ELException: java.lang.NullPointerException

I use primefaces single row selection data table , and i want to change a value on the selected row so this is my xhtml page
<h:form id="form">
<p:panel header="Prix des matériaux " style="width : 664px; " >
<br />
<p:dataTable id="cars" var="car" value="#{materielbean.listitemsmaterielBean}"
rowKey="#{car.iditemsmateriel}" paginator="true" rows="20"
selection="#{materielbean.selecteditemforprix}" selectionMode="single" >
<p:ajax event="rowSelect" update=":form:dialog" oncomplete="PF('carDialog').show()"/>
<f:facet name="header">
Liste de de matériel
</f:facet>
<p:column headerText="Désignation" filterBy="designation" >
#{car.designation}
</p:column>
<p:column headerText="Unité">
#{car.unite}
</p:column>
<p:column headerText="Prix en DT" >
#{car.prix}
</p:column>
</p:dataTable>
<p:dialog id="dialog" header="Changer le prix d'un article" widgetVar="carDialog"
resizable="true" showEffect="fade" hideEffect="explode">
<h:panelGrid columns="3">
<h:outputText value=" #{materielbean.selecteditemforprix.designation}" />
<p:inputText value="#{materielbean.selecteditemforprix.prix}"/>
<p:commandButton value="OK" action="#{materielbean.modifprixofitem()}"
onclick="PF('carDialog').hide()" update=":form:cars" />
</h:panelGrid>
</p:dialog>
</p:panel>
</h:form>
And this is the backing bean to modify the selected object
#ManagedBean(name="materielBean")
#SessionScoped
private ItemsMateriel selecteditemforprix;
public ItemsMateriel getSelecteditemforprix() {
return selecteditemforprix;
}
public void setSelecteditemforprix(ItemsMateriel selecteditemforprix) {
this.selecteditemforprix = selecteditemforprix;
}
public void modifprixofitem() {
itemmaterielDAO.Modifitemsmateriel(selecteditemforprix );
selecteditemforprix = new ItemsMateriel();
}
When I click "OK" I take the new value from the inputtext, update my object in the database and finally I update the data table, but when I did it like that, I got an error which says
22:16:48,999 GRAVE [javax.enterprise.resource.webcontainer.jsf.context] (http-localhost-127.0.0.1-8383-6) javax.el.ELException: /Gestionstock/Materiel/Matos.xhtml #28,97 rowKey="#{car.iditemsmateriel}": java.lang.NullPointerException
Well the problem is in the last lign selecteditemforprix = new ItemsMateriel(); i don't really know what's the problem with that lign but when i deleted it everything works fine, any other clarifications will be appreciated .

Primefaces p:datatable adding and editing rows not working

I'm having problems with relatively simple JSF2 site with Primefaces. I'm using Primefaces 3.5 and WebSphere Application Server v7.0
I have a page with a p:datatable which displays documents. I would like to be able to add, edit and delete said documents with a confirm/input -dialog. But when I click the Add document -button, input the name for the document and click Save, only an empty row apperas to the table. When I click the edit button and give it a proper name it is saved accordingly. But if I try to edit another row, the dialog displays the last document's name I edited.
There might be something wrong with the references, but I can't wrap my head around it. I have tried to research the subject but whit no avail. When a new document is added(or edited) the setter is called twice so I wonder if it has anything to do with this http://code.google.com/p/primefaces/issues/detail?id=4681
Here's the code-files:
test.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>test</title>
<meta http-equiv="Content-Type"
content="application/xhtml+xml; charset=UTF-8" />
</h:head>
<h:body>
<h:form>
<p:dataTable var="document" value="#{testMB.list}" id="documentTable"
paginator="true" rows="15" paginatorPosition="bottom"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
emptyMessage="No documents">
<f:facet name="header">
List of documents
</f:facet>
<p:column headerText="Document">
<h:outputText value="#{document.name}" />
</p:column>
<p:column width="70">
<p:commandButton icon="ui-icon-trash"
oncomplete="deleteDocumentDlg.show()"
style="float:right;width:32px;height:32px;top-margin:0px;bottom-margin:0px;top-padding:0px;bottom-padding:0px;">
<f:setPropertyActionListener value="#{document}"
target="#{testMB.document}" />
</p:commandButton>
<p:commandButton icon="ui-icon-pencil"
oncomplete="editDocumentDlg.show()"
style="float:right;width:32px;height:32px;top-margin:0px;bottom-margin:0px;top-padding:0px;bottom-padding:0px;"
action="#{testMB.saveChangesToDocument}">
<f:setPropertyActionListener value="#{document}"
target="#{testMB.document}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:commandButton value="New document"
oncomplete="newDocumentDlg.show()" style="float:right" />
<!-- Add new document -dialog -->
<p:dialog widgetVar="newDocumentDlg" id="newDocumentDialog"
header="Add new document" message="Add new document"
hideEffect="fade" showEffect="fade" resizable="true" closable="true"
lazy="true" width="600">
<h:panelGrid columns="3">
<h:outputText value="Name" />
<p:spacer width="10" height="10" />
<p:inputText value="#{testMB.document.name}" width="35"
maxlength="128" />
</h:panelGrid>
<br />
<h:panelGroup layout="block" style="text-align: right">
<p:commandButton value="Save" action="#{testMB.addDocument}"
oncomplete="newDocumentDlg.hide();" update="documentTable">
</p:commandButton>
<p:commandButton value="Cancel" oncomplete="newDocumentDlg.hide();"
action="#{testMB.cancelAction}" />
</h:panelGroup>
</p:dialog>
<!-- Delete document -dialog -->
<p:dialog widgetVar="deleteDocumentDlg" id="deleteDocumentDialog"
header="Delete document" message="Delete document" hideEffect="fade"
showEffect="fade" resizable="false" closable="true" lazy="true">
<h:outputText value="Delete document?" />
<h:panelGroup layout="block" style="text-align: right">
<p:commandButton value="Delete" action="#{testMB.deleteDocument}"
oncomplete="deleteDocumentDlg.hide();" update="documentTable">
</p:commandButton>
<p:commandButton value="Cancel"
oncomplete="deleteDocumentDlg.hide();"
action="#{testMB.cancelAction}" />
</h:panelGroup>
</p:dialog>
<p:dialog widgetVar="editDocumentDlg" id="editDocumentDialog"
header="Edit document" message="Edit document" hideEffect="fade"
showEffect="fade" resizable="true" closable="true" lazy="true"
width="600">
<h:panelGrid columns="3">
<h:outputText value="Name" />
<p:spacer width="10" height="10" />
<p:inputText value="#{testMB.document.name}" width="35"
maxlength="128" />
</h:panelGrid>
<br />
<h:panelGroup layout="block" style="text-align: right">
<p:commandButton value="Save" action="#{testMB.saveChanges}"
oncomplete="editDocumentDlg.hide();" update="documentTable">
</p:commandButton>
<p:commandButton value="Cancel" oncomplete="editDocumentDlg.hide();"
action="#{testMB.cancelAction}" />
</h:panelGroup>
</p:dialog>
</h:form>
</h:body>
</html>
testMB.java
import Document
#ManagedBean
#ViewScoped
public class testMB implements Serializable {
private Document document;
ArrayList<Document> list;
#PostConstruct
public void alusta() {
System.err.println("POSTCONSTRUCT");
document = new Document();
list = new ArrayList();
}
public String addDocument() {
System.err.println("Adding new document: " + document.getName());
list.add(document);
document = new Document();
return null;
}
public String deleteDocument() {
System.err.println("Deleting document: " + document.getName());
list.remove(document);
document = new Document();
return null;
}
public String saveChanges() {
System.err.println("Saving changes to document: " + document.getName());
list.get(list.indexOf(document)).setName(document.getName());
document = new Document();
return null;
}
public String cancelAction() {
document = new Document();
return null;
}
public void setDocument(Document document) {
System.err.println("Document set to: " + document.getName());
this.document = document;
}
public Document getDocument() {
return document;
}
public void setList(ArrayList<Document> list) {
this.list = list;
}
public ArrayList<Document> getList() {
return list;
}
}
Document.java
public class Document {
private String name;
public Document() {
System.out.println("Document's constructor");
name = null;
}
public Document(Document src) {
System.out.println("Document's copy constructor");
this.name = src.name;
}
public void setName(String name) {
System.err.println("Name set to " + name);
this.name = name;
}
public String getName() {
return name;
}
}
I'd be grateful for your feedback.
Your code has some problems . But the problem I can see is here
<!-- Add new document -dialog -->
<p:dialog widgetVar="newDocumentDlg" id="newDocumentDialog"
header="Add new document" message="Add new document"
hideEffect="fade" showEffect="fade" resizable="true" closable="true"
lazy="true" width="600">
<h:panelGrid columns="3">
<h:outputText value="Name" />
<p:spacer width="10" height="10" />
<p:inputText value="#{testMB.document.name}" width="35"
maxlength="128" />
</h:panelGrid>
You cannot set input text to current document name.
Instead use another variable to hold value for new document name like
private String newName;
public String getNewName() {
return newName;
}
public void setNewName(String newName) {
this.newName = newName;
}
Then change your jspx
<h:panelGrid columns="3">
<h:outputText value="Name" />
<p:spacer width="10" height="10" />
<p:inputText value="#{testMB.newName}" width="35"
maxlength="128" />
</h:panelGrid>
then your addDocument() becomes
document.setName(newName);
documentList.add(document);
document = new Document();
I hope that helps.

CDI params in #PostConstruct

I think my question is similar to this but haven't found it to work
<f:metadata>
<f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
</f:metadata>
Why can't I do this with #Named and utilize CDI:
#Named
#RequestScoped
public class DetailsBean {
private Contacts detailsContact;
#EJB
ContactsFacade contactsEJB;
private int id;
public DetailsBean() {
System.out.println("details bean called");
}
#PostConstruct
public void onLoad() {
detailsContact = contactsEJB.find(id);
}
I'm not able to log the id.
Of course, #ManagedProperty is incompatible with CDI.
*****UPDATE*****
some xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="../template.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="head">
<f:metadata>
<f:viewParam name="paginator" value="#{contactsBean.contactsTablePaginator}"/>
<f:viewParam name="rows" value="#{contactsBean.contactsTableRows}"/>
</f:metadata>
</ui:define>
<ui:define name="content">
<p:growl id="growl" showDetail="true"/>
<p:panel id="contactsPanel" >
<h:form id ="contactsForm">
<p:dataTable id="contactsTable" value="#{contactsBean.contacts}" selection="#{detailsBean.detailsContact}" var="contacts" widgetVar="contactsTable"
selectionMode="single" rowSelectListener="#{contactsBean.rowSelect}" rowUnselectListener="#{contactsBean.rowUnSelect}"
onRowUnselectUpdate="detailsForm" onRowSelectUpdate="detailsForm"
paginator="#{contactsBean.contactsTablePaginator}" rows="#{contactsBean.contactsTableRows}" rowsPerPageTemplate="5,10,15,25,50,100"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search:" />
<p:inputText id="globalFilter" onkeyup="contactsTable.filter()" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column filterStyle="display:none" filterBy="#{contacts.name}" headerText="Name" style="width:200px">
<h:outputText value="#{contacts.name}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.street}" headerText="Street" style="width:280px">
<h:outputText value="#{contacts.street}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.city}" headerText="City" style="width:150px">
<h:outputText value="#{contacts.city}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.state}" headerText="State" style="width:50px">
<h:outputText value="#{contacts.state}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.zip}" headerText="Zip" style="width:100px">
<h:outputText value="#{contacts.zip}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.country}" headerText="Country" style="width:150px">
<h:outputText value="#{contacts.country}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.sent}" headerText="Sent" style="width:50px">
<h:outputText value="#{contacts.sent}" />
</p:column>
</p:dataTable>
<p:ajaxStatus >
<f:facet name="start">
<h:graphicImage value="../resources/images/ajax-loader-bar.gif" />
</f:facet>
<f:facet name="complete">
<h:graphicImage value="../resources/images/ajax-loader-bar-still.gif" />
</f:facet>
<f:facet name="default">
<h:graphicImage value="../resources/images/ajax-loader-bar-still.gif" />
</f:facet>
</p:ajaxStatus>
<br />
<p:commandLink value="View All" action="#{contactsBean.viewAll}" />
<p:commandLink value="Default View" action="#{contactsBean.viewDefault}" />
<p:commandLink value="Advanced Search" action="search?faces-redirect=true" />
<br />
</h:form>
<br />
</p:panel>
<br />
<br />
<h:form id="detailsForm">
<p:panel id="detailsPanel" visible="#{detailsBean.visible}" >
<h:panelGrid id="detailsPanelGrid" cellpadding="2" cellspacing="2" columns="3" >
<h:outputText value="Name :" />
<p:inputText id="name" value="#{detailsBean.detailsContact.name}" style="width:400px" />
<p:message for="name" />
<h:outputText value="Email :" />
<p:inputText id="email" value="#{detailsBean.detailsContact.email}" style="width:400px" validatorMessage="Must be a valid email address. EX: test#test.com" >
<f:validateRegex pattern="[a-zA-Z0-9]+#[a-zA-Z0-9]+\.[a-zA-Z0-9]+"/>
<p:ajax event="blur" update="emailMsg" />
</p:inputText>
<p:message id="emailMsg" for="email" />
<h:outputText value="Street :" />
<p:inputText id="street" value="#{detailsBean.detailsContact.street}" style="width:400px" />
<p:message for="street" />
<h:outputText value="City :" />
<p:inputText id="city" value="#{detailsBean.detailsContact.city}" style="width:400px" />
<p:message for="city" />
<h:outputText value="State :" />
<p:inputText id="state" value="#{detailsBean.detailsContact.state}" style="width:400px" validatorMessage="Length is greater than 2" >
<f:validateLength maximum="2" />
<p:ajax event="blur" update="stateMsg" />
</p:inputText>
<p:message id="stateMsg" for="state" />
<h:outputText value="Country :" />
<p:inputText id="country" value="#{detailsBean.detailsContact.country}" style="width:400px" />
<p:message for="country" />
<h:outputText value="Phone :" />
<p:inputText id="phone" value="#{detailsBean.detailsContact.phone}" style="width:400px"/>
<p:message for="phone" />
<h:outputText value="Guests :" />
<p:inputText id="guests" value="#{detailsBean.detailsContact.guests}" style="width:400px"/>
<p:message for="guests" />
<h:outputText value="Arrival :" />
<p:calendar id="arrival" value="#{detailsBean.detailsContact.arrival}" showOn="button" />
<p:message for="arrival" />
<h:outputText value="Departure :" />
<p:calendar id="departure" value="#{detailsBean.detailsContact.departure}" showOn="button" />
<p:message for="departure" />
<h:outputText value="Message :" />
<p:inputTextarea id="message" effectDuration="30" style="width:400px;height:100px;" value="#{detailsBean.detailsContact.message}" />
<p:message for="message" />
<h:outputText value="Departure :" />
<p:calendar id="inserted" value="#{detailsBean.detailsContact.inserted}" showOn="button"/>
<p:message for="inserted" />
<h:outputText value="Sent :" />
<h:selectBooleanCheckbox id="sent" value="#{detailsBean.detailsContact.sent}" />
<p:message for="sent" />
<br />
</h:panelGrid>
<p:commandButton value="Submit" action="#{detailsBean.updateContactDetails}" update="contactsForm, growl, stateMsg" />
<p:commandButton value="Close" action="#{detailsBean.handleClose}" update="contactsForm, detailsForm" />
</p:panel>
</h:form>
</ui:define>
</ui:composition>
more java code:
package com.atlanticpkg.view.beans;
import com.atlanticpkg.model.entities.Contacts;
import com.atlanticpkg.util.FacesUtils;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
#Named(value = "detailsBean")
#RequestScoped
public class EditBean {
private Contacts detailsContact;
private boolean visible = false;
#Inject
ContactsBean contactsBean;
public EditBean() {
}
#PostConstruct
public void onLoad() {
}
public void handleClose() {
this.setVisible(false);
this.setDetailsContact(new Contacts());
}
public void updateContactDetails() {
try {
contactsBean.getContactsEJB().edit(detailsContact);
FacesUtils.addMessage(detailsContact.getName() + " was updated successfully!");
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", e.toString()));
}
}
}
and even more:
#Named(value = "contactsBean")
#RequestScoped
public class ContactsBean {
#Inject
EditBean editBean;
#EJB
private ContactsFacade contactsEJB;
private List<Contacts> contacts = new ArrayList<Contacts>();
private boolean contactsTablePaginator = true;
private int contactsTableRows = 10;
private Contacts selectedContact = new Contacts();
public ContactsBean() {
}
#PostConstruct
public void onLoad() {
updateContactsList();
}
public String viewDefault() {
contactsTablePaginator = true;
contactsTableRows = 10;
return "index?faces-redirect=true&includeViewParams=true";
}
public String viewAll() {
contactsTablePaginator = false;
contactsTableRows = 100;
return "index?faces-redirect=true&includeViewParams=true";
}
public void updateContactsList() {
contacts.clear();
contacts = contactsEJB.findAll();
}
public void rowSelect(SelectEvent event) {
editBean.setVisible(true);
editBean.setDetailsContact((Contacts) event.getObject());
}
public void rowUnSelect(UnselectEvent event) {
editBean.setVisible(false);
editBean.setDetailsContact(new Contacts());
}
}
The inputText boxes populate fine. But soon as I hit submit it says that the values are null. This code works perfectly with SessionScope.
WARNING: /admin/index.xhtml #104,109 value="#{detailsBean.detailsContact.name}": Target Unreachable, 'null' returned null
javax.el.PropertyNotFoundException: /admin/index.xhtml #104,109 value="#{detailsBean.detailsContact.name}": Target Unreachable, 'null' returned null
I can see that it's calling the EditBean when I select the data table. It then calls it again when I click the submit button.
I encountered the exact same problem than you, and solved it by using the external context (containing GET parameters) instead of f:viewParam.
In your #PostConstruct method, just get your parameter with something like
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
The lifecycle doesn't allow your approach.
At first, the bean is created ( constructor ). After that, there is executed dependency injection which is followed by #PostConstruct method and after that the JSF file is evaluated. And the viewParam is in that file. So you have to register another listener which is called after filling view params.
I have a solution for #RequestScope beans, but if the bean's scope is longer ( like View ) then this method is executed after each request ( including AJAX ) which is not probably desired.
Use this for request scope beans:
<f:metadata>
<f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
<f:event type="preRenderView" listener="#{detailsBean.onLoad}" />
</f:metadata>
For #ViewScope beans I am using this "hack" which works but probably is not best practise. It does same thing but probably it isn't the correct approach.
#{detailsBean.onLoad()}
<f:metadata>
<f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
</f:metadata>
I hope that this is helpful for you.
EDIT:
you are using a lot of AJAX here. This calls have to land in at least ViewScoped beans. View Scope is similar to RequestScope, but it takes a quite longer - til the page is left.
But I haven't read it all, there is a lot of code and if the ViewScope doesn't help then maybe you should provide the small piece of problematic code to be chance there to find and focus on the real problem.

Categories