Primefaces command button does not update datatable - jsf-2

I have primefaces command button multiple update problem. Command button is inside a form and datatable is not.
I have tried:
update=":datalist1,form1"
update=":datalist1 form1"
update="datalist1 form1"
update=":#{p:component('datalist1')},form1"
form1 updates every time but still dattable does not update
Version info:
primefaces: 5.3
jsf: org.glassfish 2.3.0-m04
spring: 4.2.3
and I use cdi for controller beans
Page:
<!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></h:head>
<body>
<h:form id="form1" >
<h:panelGrid columns="3">
<h:outputLabel value="Name: " for="name" />
<p:inputText id="name" value="#{personelController.personel.adi}" required="true" requiredMessage="Name can not be null" />
<p:message id="nameMsg" for="name" />
<h:outputLabel value="Surname: " for="surname" />
<p:inputText id="surname" value="#{personelController.personel.soyadi}" required="true" requiredMessage="Surname can not be null" />
<p:message id="surnameMsg" for="surname" />
<h:outputLabel value="Age: " for="age" />
<p:inputText id="age" value="#{personelController.personel.yasi}" required="true" requiredMessage="Age can not be null" />
<p:message id="ageMsg" for="age" />
<h:outputLabel value="Job: " for="job" />
<p:inputText id="job" value="#{personelController.personel.meslek}" required="true" requiredMessage="Job can not be null" />
<p:message id="jobMsg" for="job" />
<h:outputLabel value="City" for="city" />
<p:inputText id="city" value="#{personelController.personel.sehir}" required="true" requiredMessage="City can not be null" />
<p:message id="cityMsg" for="city" />
<p:commandButton id="add" value="Add" actionListener="#{personelController.createPersonel()}" update=":datalist1,form1" />
</h:panelGrid>
</h:form>
<p:dataTable id="datalist1" var="person" value="#{personelController.personels}" resizableColumns="true">
<f:facet name="header">List of Personel</f:facet>
<p:column headerText="ID">
<h:outputText value="#{person.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{person.adi}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{person.soyadi}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{person.yasi}" />
</p:column>
<p:column headerText="Job">
<h:outputText value="#{person.meslek}" />
</p:column>
<p:column headerText="City">
<h:outputText value="#{person.sehir}" />
</p:column>
</p:dataTable>
</body>
</html>
Class:
#Named
#SpringViewScoped
public class PersonelController implements Serializable{
private static final long serialVersionUID = 1L;
#Inject
private PersonelService personelService;
private List<Personel> personels;
private List<Personel> selectedPersonel;
private Personel personel;
#PostConstruct
public void init(){
personels=personelService.findAll();
personel=new Personel();
}
public PersonelService getPersonelService() {
return personelService;
}
public void setPersonelService(PersonelService personelService) {
this.personelService = personelService;
}
public List<Personel> getPersonels() {
return personels;
}
public void setPersonels(List<Personel> personels) {
this.personels = personels;
}
public List<Personel> getSelectedPersonel() {
return selectedPersonel;
}
public void setSelectedPersonel(List<Personel> selectedPersonel) {
this.selectedPersonel = selectedPersonel;
}
public Personel getPersonel() {
return personel;
}
public void setPersonel(Personel personel) {
this.personel = personel;
}
public void createPersonel(){
System.out.println("Personel adding..");
personelService.create(personel);
personel=new Personel();
System.out.println("Personel added");
}
}
I have researched about primefaces command button update but all advices did not worked for me. Thank you in advance

It seems to me that the newly created personel it never added to the list. So you must for example say
personels.add(personel);
or
personels=personelService.findAll();
in createPersonel(), or set personels to null and do a lazy load in getPersonels().

Related

primefaces accordionPanal dynamic disable tab

I have 2 tab in accordionPanel (tab1 and tab2), tab2 is disabled by default, and tab activeIndex is -1 by default.
I want the tab2 be enable if i check on the checkbox in tab1.
I tried by update the whole accordionPanel(bbb), but the tab1 will collapse as default.
method1:
xhtml:
<h:form id="aaa">
<p:accordionPanel id="bbb" activeIndex="#{beanPage.testdd}" widgetVar="accordionPanelWidget">
<p:tab id="tab1">
<f:facet name="title">
<h:panelGroup columns="2">
<h:selectBooleanCheckbox id="chkBox1" value="#{beanPage.testbb}">
<p:ajax global="false" event="click" update=":aaa:bbb:chkBox1,:aaa:bbb" listener="#{beanPage.testcc}" />
</h:selectBooleanCheckbox>
<h:outputText value="tab1" />
</h:panelGroup>
</f:facet>
<h:outputText value="tab1" />
</p:tab>
<p:tab id="tab2" disabled="#{appealPage.testaa}">
<f:facet name="title">
<h:panelGroup columns="2">
<h:selectBooleanCheckbox id="chkBox2" value="#{appealPage.testee}">
<p:ajax global="false" event="click" update=":aaa:bbb:chkBox2" />
</h:selectBooleanCheckbox>
<h:outputText value="tab2" />
</h:panelGroup>
</f:facet>
<h:outputText value="tab2" />
</p:tab>
</p:accordionPanel>
</h:form>
beanPage:
public void init() {
setTestaa(true);
setTestbb(false);
setTestee(false);
setTestdd(-1);
}
public void testcc() {
boolean result = isTestbb();
if (result) {
setTestaa(false);
} else {
setTestaa(true);
}
}
Try this.
I removed the panelGroups.
This is what you need?
XHTML CODE
<html 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"
>
<h:head>
<style>
</style>
</h:head>
<h:body>
<h:form id="aaa">
<p:accordionPanel id="bbb" activeIndex="#{beanPage.testdd}" widgetVar="accordionPanelWidget">
<p:tab id="tab1" title="LA primera">
<f:facet name="title">
<h:selectBooleanCheckbox id="chkBox1" value="#{beanPage.testbb}">
<p:ajax global="false" event="click" update=":aaa:bbb:chkBox1,:aaa:bbb" listener="#{beanPage.testcc}" />
</h:selectBooleanCheckbox>
<h:outputText value="tab1" />
<h:outputText value="tab1" />
</f:facet>
</p:tab>
<p:tab id="tab2" disabled="#{beanPage.testaa}">
<f:facet name="title">
<h:selectBooleanCheckbox id="chkBox2" value="#{beanPage.testee}">
<p:ajax global="false" event="click" update=":aaa:bbb:chkBox2" />
</h:selectBooleanCheckbox>
<h:outputText value="tab2" />
<h:outputText value="tab2" />
</f:facet>
</p:tab>
</p:accordionPanel>
</h:form>
</h:body>
</html>
JAVA CODE
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name="beanPage")
#ViewScoped
public class BeanPage {
public boolean testaa;
public boolean testbb;
public boolean testee;
public int testdd;
public BeanPage() {
System.out.println("1");
setTestaa(true);
setTestbb(false);
setTestee(false);
setTestdd(-1);
}
public void testcc() {
boolean result = isTestbb();
if (result) {
setTestaa(false);
} else {
setTestaa(true);
}
}
public boolean isTestaa() {
return testaa;
}
public void setTestaa(boolean testaa) {
this.testaa = testaa;
}
public boolean isTestbb() {
return testbb;
}
public void setTestbb(boolean testbb) {
this.testbb = testbb;
}
public boolean isTestee() {
return testee;
}
public void setTestee(boolean testee) {
this.testee = testee;
}
public int getTestdd() {
return testdd;
}
public void setTestdd(int testdd) {
this.testdd = testdd;
}
}

Update managed bean with ajax ignoring the required

I want to update idOutput everytime that I change the value of selectOneMenu, but when it changes once a time to a value different of null I can't asign null another time, I think that is due to the required="true", but I don't know how to avoid the validation only in the ajax request.
Here is the code:
Bean:
#ViewScoped
#ManagedBean
public class ProbeNull implements Serializable
{
private static final long serialVersionUID = 1628174277372407129L;
private Boolean probe;
public ProbeNull()
{
super();
}
public void show()
{
System.err.println("Value : " + probe);
}
public void save()
{
System.err.println("Save : " + probe);
}
public Boolean getProbe()
{
return probe;
}
public void setProbe(Boolean probe)
{
System.err.println("Setter: " + probe);
this.probe = probe;
}
}
xhtml:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:outputText id="idOutput" value="#{probeNull.probe}" />
<h:form id="form">
<p:selectOneMenu id="select" required="true" value="#{probeNull.probe}">
<f:selectItem itemLabel="Select one" itemValue="#{null}" />
<f:selectItem itemLabel="Yes" itemValue="true" />
<f:selectItem itemLabel="No" itemValue="false" />
<p:ajax update=":idOutput" />
</p:selectOneMenu>
<p:commandButton value="Save" ajax="false" action="#{probeNull.save()}" />
</h:form>
<h:form>
<p:commandButton value="Show value" ajax="false" action="#{probeNull.show()}" />
</h:form>
</h:body>
</html>
How can avoid it?
You can do what you want by using two remoteCommand tags and JavaScript.
<p:remoteCommand name="makeSelection" process="select" update=":idOutput" />
<p:remoteCommand name="clearSelection" process="#this" update="select,:idOutput" >
<f:setPropertyActionListener value="#{null}" target="#{probeNull.probe}" />
</p:remoteCommand>
Now you can decide which one to call using a javascript funcion
<p:selectOneMenu id="select" required="true" value="#{probeNull.probe}" onchange="selectFunction(this)">
...
function selectFunction(el){
//if el.value is empty you call clearSelection();
//else you call makeSelection();
}
Don't forget to delete the <p:ajax update=":idOutput" />

Pagination on Primefaces datatable doesn't work

I am currently developing an application with JPA2, Spring 3, MyFaces 2.1 and Primefaces 4.0 RC1.
I developed a simple page with one datatable using pagination feature of primefaces, but when I click on page number (bottom or header), it simply doesn't work. No exception or javascript error is shown.
I've tested both in Chrome and Firefox. Same problem.
Here my code:
#ManagedBean
#ViewScoped
public class MeusCelularesTitularMB extends AbstractMB implements Serializable {
private static final long serialVersionUID = 5446365969371398743L;
private static final Logger logger = LogManager.getLogger(MeusCelularesTitularMB.class);
private CadastroGeral loggedUser;
private List<LinhaCelularTitular> listaCelularesTitular;
#PostConstruct
public void init() {
try {
this.loggedUser = getCadastroGeralService().loadUser(getAuthenticatedUser());
this.listarMeusCelularesTitular();
} catch (ServiceException e) {
logger.error("Erro ao consultar banco de dados", e);
throw new RuntimeException(e);
}
}
private void listarMeusCelularesTitular() {
try {
this.listaCelularesTitular = getLinhaCelularTitularSevice().getLinhasCelularesPorReponsavel(this.loggedUser.getMatricula());
} catch (ServiceException e) {
logger.error("Erro ao consultar banco de dados", e);
throw new RuntimeException(e);
}
}
private static CadastroGeralService getCadastroGeralService() {
return Faces.evaluateExpressionGet("#{cadastroGeralService}");
}
private static LinhaCelularTitularService getLinhaCelularTitularSevice() {
return Faces.evaluateExpressionGet("#{linhaCelularTitularService}");
}
public List<LinhaCelularTitular> getListaCelularesTitular() {
return listaCelularesTitular;
}
public void setListaCelularesTitular(List<LinhaCelularTitular> listaCelularesTitular) {
this.listaCelularesTitular = listaCelularesTitular;
}
}
And the XHTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="../../templates/template.xhtml">
<ui:define name="content">
<h:outputStylesheet library="css" name="meusCelulares.css" />
<h:form id="meusCelularesTitulares">
<p:ajaxStatus onstart="statusDialog.show();" onsuccess="statusDialog.hide();"/>
<h2>Celulares - Titular</h2>
<p:dataTable id="tblLinhaCelularesTitulares"
var="celTitular"
widgetVar="wdgLinhaCelularesTitulares"
value="#{meusCelularesTitularMB.listaCelularesTitular}"
rowKey="#{celTitular.id}"
paginator="true"
rows="10"
rowsPerPageTemplate="5,10,15"
emptyMessage="Nenhum celular encontrado na Base de Dados">
<p:column>
<f:facet name="header">
<h:outputText value="Ações" />
</f:facet>
<h:outputText value="A B C" />
</p:column>
<p:column styleClass="colunaCentralizada">
<f:facet name="header">
<h:outputText value="Código DDD" />
</f:facet>
<h:outputText value="#{celTitular.codigoDDD}" />
</p:column>
<p:column styleClass="colunaCentralizada">
<f:facet name="header">
<h:outputText value="Número" />
</f:facet>
<h:outputText value="#{celTitular.numeroLinha}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Nome" />
</f:facet>
<h:outputText value="#{celTitular.responsavel.nome}" />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
</html>
If you need some more information, please let me know.
Found the solution! Thanks to #XtremeBiker for the hints.
The <p:ajaxStatus onstart="statusDialog.show();" onsuccess="statusDialog.hide();"/> is referencing a dialog box that I forgot to add in the XHTML. So I added the code below and it worked.
<p:dialog modal="true"
widgetVar="statusDialog"
header="Aguarde..."
draggable="false"
closable="false"
resizable="false"
width="245"
height="25" >
<div align="center">
<p:graphicImage value="/resources/images/ajax-loader.gif" />
</div>
</p:dialog>
I use this code to block screen when a ajax request is processing.
Thanks again.

PrimeFaces datatable not refreshing correctly after an add operation

I have a datatable which has add edit delete and filter operations.
All the operations are working fine on the database but the datatable is not updating correctly after an add operation.
It is updated correctly after the 1st add operation.
when I add 2nd row the datatable is updated but the row which was added first is replaced with the row which was added 2nd but in the db they are updated correctly.
similarly when I add a 3rd row the 1st row is replaced with the 3rd row.
Software stack used in the CRUD dataTable application are :- PrimeFace 3.4.2,JSF 2.1,NetBeans 7.2.1,Java 1.6.0_37 GlassFish 3.1.x,MySql 5.x
This is my code.
**xhtml page**
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Prime Faces Data table</title>
</h:head>
<h:body>
<h:form id="form1">
<h:messages id="messages1"/>
<br/>
<p:commandButton id="Addbtn" value="Add" oncomplete="AddDialog.show()"
update=":addform"/>
<br/>
<p:dataTable id="dtusers" value="#{userdataController.retrieveData()}"
var="item"
rows="8" paginator="true" emptyMessage="No Records Found"
paginatorAlwaysVisible="false">
<p:column style="width:150px" filterMatchMode="contains"
filterBy ="#{item.id}">
<f:facet name="header"> Id </f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<p:column style="width:150px" filterMatchMode="contains"
filterBy="#{item.name}">
<f:facet name="header"> Name </f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column style="width:150px">
<p:commandButton id="editButton" update=":editform"
oncomplete="EditDialog.show()" value="Edit">
<f:setPropertyActionListener value="#{item}"
target="#{userdataController.selectedUser}"/>
</p:commandButton>
</p:column>
<p:column style="width:150px">
<p:commandButton id="deleteButton" update=":deleteform"
oncomplete="UserDialog.show()" value="Delete">
<f:setPropertyActionListener value="#{item}"
target="#{userdataController.selectedUser}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<p:dialog header="Add User Data" resizable="false" id="AddDialog"
widgetVar="AddDialog" modal="true" showEffect="fade" hideEffect="fade"
position="center" >
<h:form id="addform">
<p:outputPanel id="AddDisplay">
<p:panelGrid columns="2" >
<f:facet name="header">
Add Userdata
</f:facet>
<h:outputLabel for="Id" value="Enter Id:"/>
<p:inputText id="Id" value="#{userdataController.selected.id}" />
<h:outputLabel for="Name" value="Enter Name:"/>
<p:inputText id="Name"
value="#{userdataController.selected.name}"/>
<p:commandButton actionListener="#{userdataController.createdata}"
update=":form1:dtusers :form1:messages1" value="Save"
oncomplete="AddDialog.hide()" style="margin:0"/>
</p:panelGrid>
</p:outputPanel>
</h:form>
</p:dialog>
//similarly dialogs for delete and edit
</h:body>
</html>
**ManagedBean**
#ManagedBean(name = "userdataController")
#SessionScoped
public class UserdataController implements Serializable {
private Userdata current;
private DataModel items = null;
#EJB
private PrimeFacesDb.session.UserdataFacade ejbFacade;
private int id;
private String name;
private Userdata SelectedUser;
public UserdataController() {
}
//getters setters for id,name and SelectedUser
private UserdataFacade getFacade() {
return ejbFacade;
}
public List retrieveData() {
List result = getFacade().findAll();
return result;
}
public void create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage("Userdata created successfully");
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Persistence Error occured");
}
}
}

JSF 2 basic #RequestScoped CRUD

i have these simple pages:
list.xhtml
<h:form id="form">
<h:dataTable value="#{testBean.model}" var="elem">
<h:column>
<f:facet name="header">code</f:facet>
#{elem.code}
</h:column>
<h:column>
<f:facet name="header">description</f:facet>
#{elem.description}
</h:column>
<h:column>
<f:facet name="header">action</f:facet>
<h:commandButton action="#{testBean.edit(elem)}" value="edit"/>
</h:column>
</h:dataTable>
</h:form>
edit.xhtml
<h:form id="form">
<h:panelGrid columns="2">
<h:outputLabel value="code"/>
<h:inputText value="#{testBean.selection.code}"/>
<h:outputLabel value="description"/>
<h:inputText value="#{testBean.selection.description}"/>
</h:panelGrid>
<h:commandButton action="#{testBean.update}" value="update"/>
</h:form>
and this bean:
#ManagedBean
public class TestBean implements Serializable
{
private static final long serialVersionUID = 1L;
#EJB
private PersistenceService service;
private Object selection;
private List<UnitType> model;
#PostConstruct
public void init()
{
model = service.findAll(UnitType.class);
}
public String edit(Object object)
{
System.out.println(Tracer.current(object));
setSelection(object);
return "edit";
}
public String update()
{
System.out.println(Tracer.current(selection));
return "list";
}
// getters and setters
}
so the table is rendered, when i click one of the "edit" buttons it navigates to "edit.jsf" showing filled input,
but when i click the "update" buttons it gives me this error:
javax.el.PropertyNotFoundException: /test2/edit.xhtml #27,54 value="#{testBean.selection.code}": Target Unreachable, 'null' returned null
note that i know how to implement a #ViewScoped interface to manage CRUD operations, but this is a simple proof of concept that i need to better understand JSF lifecycle.
so i want "testBean" to be #RequestScoped
UPDATE trying with f:viewParam, still not understanding...
list.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>test list</title>
</h:head>
<h:body>
<h:messages/>
<h:form id="form">
<h:dataTable value="#{testBean2.model}" rows="10" var="elem">
<h:column>
<f:facet name="header">converterString</f:facet>
#{elem.converterString}
</h:column>
<h:column>
<f:facet name="header">first name</f:facet>
#{elem.firstName}
</h:column>
<h:column>
<f:facet name="header">last name</f:facet>
#{elem.lastName}
</h:column>
<h:column>
<f:facet name="header">action</f:facet>
<h:commandButton action="#{testBean2.edit}" value="edit">
<f:param name="entity" value="#{elem.converterString}"/>
</h:commandButton>
<h:commandButton action="#{testBean2.edit2}" value="edit2">
<f:param name="entity" value="#{elem.converterString}"/>
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
edit.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<f:metadata>
<f:viewParam id="entityParam" name="entity" value="#{testBean2.selection}" converter="entityConverter" required="true"/>
</f:metadata>
<h:head>
<title>test edit</title>
</h:head>
<h:body>
<h:messages/>
<h:form id="form">
<h:panelGrid columns="2">
<h:outputLabel value="selection"/>
<h:outputText value="#{testBean2.selection.converterString}"/>
<h:outputLabel value="firstName"/>
<h:inputText value="#{testBean2.selection.firstName}"/>
<h:outputLabel value="lastName"/>
<h:inputText value="#{testBean2.selection.lastName}"/>
</h:panelGrid>
<h:commandButton action="#{testBean2.update}" value="update" ajax="false">
<f:param name="entity" value="#{testBean2.selection.converterString}"/>
</h:commandButton>
</h:form>
</h:body>
</html>
testBean2.java
#ManagedBean
public class TestBean2 implements Serializable
{
private static final long serialVersionUID = 1L;
#EJB
private PersistenceService service;
private Object selection;
private List<Person> model;
#PostConstruct
public void init()
{
Tracer.out();
model = service.queryAll(Person.class);
}
public String edit()
{
JsfUtils.addSuccessMessage("edited");
return "edit";
}
public String edit2()
{
JsfUtils.addSuccessMessage("edited");
return "edit?faces-redirect=true&includeViewParams=true";
}
public void update()
{
Tracer.out(selection);
JsfUtils.addSuccessMessage("updated");
}
// getters and setters
}
if i press "edit" button it goes to edit page, but selection is null and no message is showed.
if i press "edit2" button it goes to edit page, but selection is null, showing required message and the url is edit.jsf?entity=
what am i doing wrong?
As my understand, when your second request come to testBean, selection Object is null. If you run this with session bean you may not get this error.
The way I see it, there's no clean way to achieve what you want.
I'll suggest you simply pass around an Id attr between requests as a simple request parameter. So in your post constructor, check if the parameter value is set and based on that, perform a look in your persistence layer.
Alternatively, using the setup you already have, bind the:
<h:inputText value="#{testBean.selection.code}"/>
component to your backing bean and call getValue() on it when necessary. Either way, still untidy.
If you find any other way, please let us know.
Finally I found a way: data will be in a long scope, bean in short.
Note that this is just a proof of concept, not a real use case. And be aware, when dealing with #RequestScope beans, of PrimeFaces lazy DataTable model scope
#ManagedBean
public class TestBean
{
#EJB
private PersistenceService service;
#ManagedProperty("#{viewScope.item}")
private Item item;
#ManagedProperty("#{sessionScope.model}")
private EntityDataModel<Item> model;
#PostConstruct
public void init()
{
if(model == null)
{
model = new EntityDataModel<Item>(Item.class);
Faces.setSessionAttribute("model", model);
}
}
public String update()
{
Faces.getFlash().setKeepMessages(true);
try
{
item = service.update(item);
Faces.setViewAttribute("item", item);
JsfUtils.addSuccessMessage("updated");
return "view?faces-redirect=true&includeViewParams=true";
}
catch(Exception e)
{
e.printStackTrace();
JsfUtils.addErrorMessage(e);
}
return null;
}
// getters and setters, other actions, ...
}
list.xhtml
<p:dataTable value="#{testBean.model}" var="elem" ...>
...
<p:column exportable="false" toggleable="false" headerText="#{bundle.actions}">
<!-- two techniques available for navigation -->
<p:button outcome="view?id=#{elem.converterString}" icon="#{icons.view}" />
<p:commandButton rendered="#{user.isEditAllowed(elem)}"
action="edit?faces-redirect=true&includeViewParams=true" process="#form"
icon="#{icons.edit}">
<f:param name="id" value="#{elem.converterString}" />
</p:commandButton>
</p:column>
</p:dataTable>
view.xhtml
<f:metadata>
<o:viewParam id="itemId" name="id" value="#{viewScope.item}" required="true"
converter="entityConverter" />
</f:metadata>
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<p:panelGrid columns="2">
<h:outputLabel value="#{bundle.name}" />
<h:outputText value="#{item.name}" />
...
</p:panelGrid>
<p:button outcome="list" value="#{bundle.list}" icon="#{icons.list}" />
<p:button rendered="#{user.isEditAllowed(item)}"
outcome="edit?id=#{item.converterString}" value="#{bundle.edit}"
icon="#{icons.edit}" />
</ui:define>
</ui:composition>
edit.xhtml
<f:metadata>
<o:viewParam id="itemId" name="id" value="#{viewScope.item}" required="true"
converter="entityConverter" />
</f:metadata>
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<p:panelGrid columns="2">
<h:outputLabel value="#{bundle.name}" />
<h:panelGroup>
<p:inputText id="name" value="#{item.name}" />
<p:message for="name" />
</h:panelGroup>
...
</p:panelGrid>
<p:commandButton process="#form" update="#form" action="#{testBean.update}"
value="#{bundle.update}" icon="#{icons.update}" />
<p:button outcome="view?id=#{item.converterString}" value="#{bundle.cancel}"
icon="#{icons.cancel}" />
</ui:define>
</ui:composition>

Resources