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.
Related
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.
I'm using JSF 2.2 in a web application and I'm having problems in the view when I use f:validateRegex and fails (because when I use immediate="true" and try to navigate to the same page again, the view isn't updated when I have a new Instance of the object in my backing bean). I was thinking richfaces has a bug (because I'm using jsf and richfaces in my main application) so I made a test code with richfaces and without richfaces (only jsf) to identify where is the error, but in both cases the view fails.
Here is my test code without richfaces (Only jsf):
View:
<?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:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head>
<title>Mis pruebas con JSF</title>
</h:head>
<h:body>
<h:form id="lista">
<h:panelGrid id="principal">
<h:dataTable value="#{indexBB.personas}" var="persona">
<h:column>
<f:facet name="header">Activo</f:facet>
<h:selectBooleanCheckbox value="#{persona.activo}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
<h:outputText value="#{persona.nombre}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">Correo</f:facet>
<h:outputText value="#{persona.correo}"></h:outputText>
</h:column>
</h:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</h:panelGrid>
</h:form>
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
Bean:
package com.kanayet.martin.view.bb;
import com.kanayet.martin.model.entity.Persona;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named(value = "indexBB")
#ViewScoped
public class indexBB implements Serializable {
private Persona persona;
private List<Persona> personas;
private boolean crear;
/**
* Creates a new instance of indexBB
*/
public indexBB() {
}
#PostConstruct
public void onInit(){
personas = new ArrayList<>();
personas.add(new Persona("Martin", "martin#gmail.com", true));
personas.add(new Persona("Andrea", "andrea#gmail.com", true));
personas.add(new Persona("Camilo", "camilo#gmail.com", true));
personas.add(new Persona("Felipe", "felipe#gmail.com", true));
personas.add(new Persona("David", "david#gmail.com", true));
}
public void activarBoton() {
persona = personas.get(0);
}
public void crearPersona(){
crear = true;
persona = new Persona();
}
public void guardarPersona(){
personas.set(0, persona);
}
public void cancelar(){
}
public Persona getPersona() {
return persona;
}
public void setPersona(Persona persona) {
this.persona = persona;
}
public List<Persona> getPersonas() {
return personas;
}
public void setPersonas(List<Persona> personas) {
this.personas = personas;
}
public boolean isCrear() {
return crear;
}
public void setCrear(boolean crear) {
this.crear = crear;
}
}
Model: (Object)
package com.kanayet.martin.model.entity;
public class Persona {
private String nombre;
private String correo;
private Boolean activo;
public Persona() {
}
public Persona(String nombre, String correo, Boolean activo) {
this.nombre = nombre;
this.correo = correo;
this.activo = activo;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getCorreo() {
return correo;
}
public void setCorreo(String correo) {
this.correo = correo;
}
public Boolean getActivo() {
return activo;
}
public void setActivo(Boolean activo) {
this.activo = activo;
}
}
Here is my test code with richfaces: (Bean and Model are the same)
View:
<?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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Mis pruebas con RichFaces</title>
</h:head>
<h:body>
<h:form id="lista">
<a4j:outputPanel id="principal">
<rich:dataTable id="personas" value="#{indexBB.personas}"
var="persona" rows="50">
<rich:column>
<h:selectBooleanCheckbox label="Activo" value="#{persona.activo}">
</h:selectBooleanCheckbox>
</rich:column>
<rich:column>
<h:outputText value="#{persona.nombre}"></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{persona.correo}"></h:outputText>
</rich:column>
</rich:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</a4j:outputPanel>
</h:form>
<br></br>
<h:form id="crear">
<a4j:outputPanel id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</a4j:outputPanel>
</h:form>
</h:body>
</html>
The problem is when I click "Crear Persona" button, I write for example "Nombre": Felix and "Correo": Felix and click "Guardar Persona" button so f:validateRegex fails because isn't a valid email, then click "Cancelar" because my final user doesn't know email required value (immediate="true"). Again, click "Crear Persona" button, (new object in my bean) and jsf page isn't updated, the form should be empty but it isn't, in field "Nombre" stills "Felix" value, but in my bean I have a new and empty object without values in its attributes, do you know why?
The problem is with and without richfaces (because I thought the problem could be richfaces, but it isn't), so I don't know why jsf page isn't updated if I have a new object in my bean, I used netbeans debug tool to verify but I'm right, the object that I see in my bean is different (server side new and empty object) but in my JSF page "Nombre" has "Felix" value and I want to know why it happens, and how I can resolve this problem.
Thank you so much.
The problem is that JSF maintains two representations of your model. There is the Java object, IndexBB, but there is also the component tree, the thing that keeps track of UI state.
When you fail validation, the component tree still contains the values entered. (This is a useful feature so that the user can correct the values.) You've used immediate=true to skip validation, but that doesn't reset the component tree values.
In JSF 2.2, you can use resetValues to reset component tree values:
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText id="nombreId" label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText id="correoId" label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton
action="#{indexBB.cancelar}" value="Cancelar">
<f:ajax resetValues="true" render="crear:nombreId crear:correoId"/>
</h:commandButton>
</h:panelGrid>
</h:form>
Changes:
Remove immediate=true.
Add ids to inputs you want to reset.
Add f:ajax to Cancelar button.
Add resetValues property to f:ajax and list your IDs (separate IDs with spaces, not comma).
Make sure your cancelar method actually resets persona -- the code you posted doesn't do this.
If you also want to reset the error messages, add an h:messages to the form, give it an ID, and reset it too.
See also
JSF 2.2: Reset input fields
How to skip validation when a specific button is clicked?
I want to update a selectOneMenu in form1 after submitting the commandbutton in form2. It is now only visible after a refresh of the page.
I have a selectOneMenu in form 1:
<h:form id="form1" rendered="#">
<p:spacer height="30" />
<h:selectOneMenu id="oneMenu" value="#{bean.value}">
<f:selectItem itemLabel="Select Value" itemValue="" />
<f:selectItems id="itemValues"
value="#{bean.allItems}" var="allItems"
itemValue="#{allItems}" itemLabel="#{allItems.name}" />
</h:selectOneMenu>
and a DialogBOX in form2:
<h:form id="form2">
<p:dialog header="Create new Item" widgetVar="newItem"
resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="item" value="Itemname:" />
<p:inputText id="itemname" value="#{bean.itemName}" />
</h:panelGrid>
<p:commandButton value="Submit"
actionListener="#{bean.newItem}"
update="form1:oneMenu" oncomplete="newItem.hide();" />
</p:dialog>
I've tried update="form1:oneMenu" but it doesn't work. I've also read this post
but it doesn't work either.
Thanks for help.
Make sure to use update=":form1:myPanel".
Example :
<h:form id="form1">
<h:selectOneMenu id="oneMenu" value="#{bean.value}">
...
</h:selectOneMenu>
</h:form>
<h:form id="form2">
<p:dialog ..>
...
<p:commandButton value="Submit" update=":form1:oneMenu" ..../>
</p:dialog>
</h:form>
Otherwise
<h:form id="form1">
<p:selectOneMenu id="oneMenu" value="#{bean.value}">
...
</p:selectOneMenu>
</h:form>
<h:form id="form2">
<p:dialog ..>
...
<p:commandButton value="Submit" update=":form1:oneMenu" ..../>
</p:dialog>
</h:form>
Update For Comment : Try that below. You can use h:selectOneMenu or p:selectOneMenu.
<h:form id="form1">
<p:selectOneMenu style="width:195px;" required="true" id="cityMenu">
<f:selectItems value="#{SelectOneMenuBean.cities}"/>
</p:selectOneMenu>
<p:commandButton oncomplete="newItem.show()" value="Show Dialog"/>
</h:form>
<h:form id="form2">
<p:dialog header="Create new Item" widgetVar="newItem" resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="item" value="Itemname:" />
<p:inputText id="itemname" value="#{SelectOneMenuBean.selectedValue}" />
</h:panelGrid>
<p:commandButton value="Submit" update=":form1:cityMenu" oncomplete="newItem.hide();" />
</p:dialog>
</h:form>
public class SelectOneMenuBean {
private String selectedValue;
public String getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(String selectedValue) {
this.selectedValue = selectedValue;
}
public String[] getCities() {
if(selectedValue != null && selectedValue.equals("AAA")) {
return new String[] {"City_1 of AAA", "City_2 of AAA", "City_3 of AAA"};
} else if(selectedValue != null && selectedValue.equals("BBB")) {
return new String[] {"City_1 of BBB", "City_2 of BBB", "City_3 of BBB"};
} else if(selectedValue != null && selectedValue.equals("CCC")) {
return new String[] {"City_1 of CCC", "City_2 of CCC", "City_3 of CCC"};
} else if(selectedValue != null && selectedValue.equals("DDD")) {
return new String[] {"City_1 of DDD", "City_2 of DDD", "City_3 of DDD"};
}
return new String[] {"No City"};
}
}
Note : If you input value AAA,BBB,CCC and DDD in dialog, the values of selectedOneMenu will be changed.
i am trying to call a property in jsf which using primefaces. but i have error 500 which not found on type managedbean.PersonelBean.
i am using hibernate jsf and spring.
PersonelBean.java
#ManagedBean(name="personelMB")
#SessionScoped
public class PersonelBean implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{PersonelService}")
IPersonelService personelservice;
List<Personel> personelList;
private int personel_id;
private String pname;
private String pfamily;
private String paddress;
private String pphone;
public IPersonelService getPersonelservice() {
return personelservice;
}
public void setPersonelservice(IPersonelService personelservice) {
this.personelservice = personelservice;
}
public List<Personel> getPersonelList() {
personelList=new ArrayList<Personel>();
personelList.addAll(getPersonelservice().getPersonels());
return personelList;
}
public void setPersonelList(List<Personel> personelList) {
this.personelList = personelList;
}
//getter and setter method
public void addPersonel(){
Personel personel=new Personel();
personel.setPaddress(getPaddress());
personel.setPersonel_id(getPersonel_id());
personel.setPfamily(getPfamily());
personel.setPname(getPname());
personel.setPphone(getPphone());
getPersonelservice().addPersonel(personel);
}
}
personel.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 dir="rtl"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>اطلاعات پرسنلی</title>
</h:head>
<h:body>
<h1>اضافه کردن پرسنل جدید</h1>
<h:form>
<h:panelGrid columns="4" >
شماره پرسنلی :
<h:inputText id="id" value="#{personelMB.personel_id}"
size="20" required="true"
label="id" >
</h:inputText>
<br></br>
نام :
<h:inputText id="name" value="#{personelMB.pname}"
size="20" required="true"
label="Name" >
</h:inputText>
نام خانوادگی:
<h:inputText id="family" value="#{personelMB.pfamily}"
size="20" required="true"
label="family" >
</h:inputText>
آدرس :
<h:inputTextarea id="address" value="#{personelMB.paddress}"
cols="30" rows="10" required="true"
label="Address" >
</h:inputTextarea>
تلفن:
<h:inputText id="tel" value="#{personelMB.pphone}"
size="20" required="true"
label="tel" >
</h:inputText>
</h:panelGrid>
<h:commandButton value="درج اطلاعات" action="#{personelMB.addPersonel()}" />
</h:form>
<h2>مشاهده اطلاعات پرسنل</h2>
<h:form prependId="false">
<p:dataTable id="dataTable" var="personel" value="#{personelMB.getPersonelList()}">
<f:facet name="header">
اطلاعات پرسنل
</f:facet>
<p:column>
<f:facet name="header">
شماره پرسنلی
</f:facet>
<h:outputText value="#{personel.personel_id}" />
<f:facet name="footer">
کدملی
</f:facet>
</p:column>
<p:column headerText="نام">
<h:outputText value="#{personel.pname}" />
</p:column>
<p:column headerText="نام خانوادگی">
<h:outputText value="#{personel.pfamily}" />
</p:column>
<p:column headerText="آدرس">
<h:outputText value="#{personel.paddress}" />
</p:column>
<p:column headerText="تلفن">
<h:outputText value="#{personel.pphone}" />
</p:column>
<f:facet name="footer">
In total there are #{fn:length(personelMB.getPersonelList())} personels.
</f:facet>
</p:dataTable>
</h:form>
</h:body>
</html>
but i have this error:
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: /personel.xhtml #58,88 value="#{personelMB.getPersonelList()}": Property 'getPersonelList' not found on type managedbean.PersonelBean
javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
root cause
javax.el.PropertyNotFoundException: /personel.xhtml #58,88 value="#{personelMB.getPersonelList()}": Property 'getPersonelList' not found on type managedbean.PersonelBean
com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:97)
org.primefaces.component.api.UIData.isLazyLoading(UIData.java:170)
org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:187)
org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:107)
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:879)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
javax.faces.render.Renderer.encodeChildren(Renderer.java:164)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:849)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1643)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1646)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1646)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:389)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:127)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:117)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:135)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:309)
i don't know what is wrong but my addPersonel() works well.
Property value expressions needs to be specified in the following syntax, without the get (or is) prefix and without the parentheses:
value="#{personelMB.personelList}"
Look at your other gettes and setters and look at explanation of exception.
/personel.xhtml #58,88 value="#{personelMB.getPersonelList()}": Property 'getPersonelList' not found on type managedbean.PersonelBean
You're using correct JSF EL (this things: #{...}) for other properties of the PersonelBean:
#{personelMB.pname} -> translates to personelMB.getPname()
`#{bean.property}' -> bean.getProperty()
but suddenly you're using:
personelMB.getPersonelList()
You should use
#{personelMB.personelList}
you can work on #{#{personelMB.getPersonelList()}, but you should need add two jar files el-ap-SNAPSHOT.jar and el-impl-SNAPSHOT.jar.
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.