Primefaces ajax row selection fail to update values in dialog - jsf-2

I have a data table that will display a detail dialog on row select event. However, the dialog does not show any values of the selected object. I can see that the selected object is properly set during debug session.
The table consists of rows of students and it is suppose to display a popup dialog showing detailed information on row selection event.
The StudentBean:
#Named(value = "studentBean")
#SessionScoped
public class StudentBean {
#Inject
private UserFacade userFacade;
private List<User> studentList;
private User selectedStudent;
public StudentBean() {
}
#PostConstruct
public void init() {
studentList = userFacade.findAll();
}
public List<User> getStudentList() {
return studentList;
}
public void setStudentList(List<User> studentList) {
this.studentList = studentList;
}
public User getSelectedStudent() {
return selectedStudent;
}
public void setSelectedStudent(User student) {
this.selectedStudent = student;
}
public void onRowSelect(SelectEvent event) {
}
public void onRowUnselect(UnselectEvent event) {
//FacesMessage msg = new FacesMessage("Student Unselected", ((User) event.getObject()).getFirstName());
//FacesContext.getCurrentInstance().addMessage("messages", msg);
}
}
The Facelet page:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h ="http://java.sun.com/jsf/html"
xmlns:p ="http://primefaces.org/ui">
<body>
<ui:composition template="./layout.xhtml">
<ui:define name="content">
<h:form id="studentForm">
<p:dataTable var="student" value="#{studentBean.studentList}"
selectionMode="single"
selection="#{studentBean.selectedStudent}" rowKey="#{student.id}">
<p:ajax event="rowSelect" listener="#{studentBean.onRowSelect}"
update=":studentForm:studentDetail" oncomplete="studentDialog.show()"
global="true" immediate="true"
/>
<p:ajax event="rowUnselect" listener="#{studentBean.onRowUnselect}" />
<p:column headerText="First Name">
<h:outputText value="#{student.firstName}" />
</p:column>
<p:column headerText="Last Name">
<h:outputText value="#{student.lastName}" />
</p:column>
<p:column headerText="Student ID">
<h:outputText value="#{student.studentid}" />
</p:column>
</p:dataTable>
<p:dialog id="dialog" header="Student Detail" widgetVar="studentDialog" resizable="false"
showEffect="fade" hideEffect="fade" appendToBody="true">
<h:panelGrid id="studentDetail" columns="2" cellpadding="4">
<h:outputText value="First Name: " />
<h:outputText value="#{studentBean.selectedStudent.firstName}" />
<h:outputText value="Last Name: " />
<h:outputText value="#{studentBean.selectedStudent.lastName}" />
</h:panelGrid>
</p:dialog>
</ui:define>
</ui:composition>
</body>
</html>
I'm following the Car data table example from the Primefaces Showcase page. It seems so simple there but I can't seem to display the selectedStudent information no matter what I do. The dialog shows up fine but the firstName and lastName values are empty.
I tried the following:
Putting the dialog into another form
Use process="#form"
Use process=":studentForm:studentDetail"
What am I doing wrong?
Primefaces 3.3.1,
Glassfish 3.1.2

I removed global="true" immediate="true", unused listeners
from p:ajax, synchronized rowKey="#{student.id}"
with expression from "Student ID" column and populated
studentList inside #PostConstruct init() function not knowing how yours userFacade code is, and it works.

Related

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.

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>

ViewScoped bean is recreated everytime I click on commandButton in my dataTable

Im using primefaces version 3.1.1, Mojarra 2.1.3, Netbeans 7.0.1, Glassfish Server 3.1.
My test application is using a facelet template with top, left, content, right and bottom layout with raw divs and css. After user logs in with container managed jdbcrealm, they will be presented with the main index.html which use the said template.
I put a navigation menu on the left panel which will subsequently update center panel content with ajax upon clicking menuitem. The center panel will be updated dynamically in <ui:include> by using sessionScoped NavigationBean.
In one of the page clientList.xhtml, I put a <p:dataTable> with a button to view the detail by popping up a <p:dialog>. Im using a viewCoped bean to hold the data list displayed on the dataTable.
The problem is, when I click on the button to select a row in the last colum of every row, the dialog does not appear at all, and my p:ajaxStatus gif image kept on rolling unendingly. When I debug the program with netbeans, I notice the constructor is called again and the previous instance is gone after clicking the button.
This is my index.xhtml using facelets template.
<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"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:composition template="/BySalesAutomationTemplate.xhtml">
<ui:define name="title">
<h:outputText value="Facelet Index Page"></h:outputText>
</ui:define>
<ui:define name="top">
TOP
</ui:define>
<ui:define name="left">
<ui:include src="users/menu#{request.isUserInRole('ADMIN') ? 'Admin' : 'User'}.xhtml" />
</ui:define>
<ui:define name="right">
<h:outputText value="Cuba2 daan"></h:outputText>
</ui:define>
<ui:define name="maincontent">
<c:if test="#{navigationBean.page!=null}">
<ui:include src="#{navigationBean.page}.xhtml" />
</c:if>
</ui:define>
<ui:define name="bottom">
<center>2012</center>
</ui:define>
</ui:composition>
</html>
This is the clientList.xhtml page which is displayed in the center panel of my index.xhtml upon clicking a link on the menu in the left panel.
<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>
<title>Client Listing</title>
</h:head>
<h:body>
<p>Client List</p>
<h:form>
<h:commandButton action="#{authBackingBean.logout}" value="Logout" />
</h:form>
<f:view>
<h:form id="formdetail" prependId="false">
<p:ajaxStatus>
<f:facet name="start">
<h:graphicImage value="images/loading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<p:growl id="growl" showDetail="true"/>
<p:dataTable id="dtClientList" value="#{saClientController.lazyModel}" rowsPerPageTemplate="10,20,30,50"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
paginatorAlwaysVisible="false" var="item" paginator="true" rows="10">
<f:facet name="header">
<h:outputText value="Client List"/>
</f:facet>
<p:column filterBy="#{item.idSaClient}">
<f:facet name="header">
<h:outputText value="IdSaClient"/>
</f:facet>
<p:commandLink action="#{saClientController.showDetails(item)}" value="#{item.idSaClient}" target=":maincontent"/>
</p:column>
<p:column filterBy="#{item.saClientName}">
<f:facet name="header">
<h:outputText value="saClientName"/>
</f:facet>
<h:outputText value="#{item.saClientName}"/>
</p:column>
<p:column filterBy="#{#item.saClientAddress}">
<f:facet name="header">
<h:outputText value="SaClientAddress"/>
</f:facet>
<h:outputText value="#{item.saClientAddress}"/>
</p:column>
<p:column style="width:40px">
<h:panelGrid columns="3" styleClass="actions" cellpadding="2">
<p:commandButton id="selectButton" update=":formdetail:display" oncomplete="clientDialog.show()" icon="ui-icon-search" title="View">
<f:setPropertyActionListener value="#{item}" target="#{saClientController.selectedSaClient}" />
</p:commandButton>
</h:panelGrid>
</p:column>
<f:facet name="footer">
<h:outputText value="Client List"/>
</f:facet>
</p:dataTable>
</h:form>
<p:dialog id="clientDialog" header="Client Detail" widgetVar="clientDialog" resizable="false" showEffect="explode" hideEffect="explode">
<h:panelGrid id="display" columns="2" cellpadding="4">
<f:facet name="header">
<h:outputText value="Selected Row" />
</f:facet>
<h:outputText value="ID" />
<h:outputText value="#{saClientcontroller.selectedSaClient.idSaClient}" />
<h:outputText value="NAME:" />
<h:outputText value="#{saClientcontroller.selectedSaClient.saClientName}" />
<h:outputText value="DESCRIPTION:" />
<h:outputText value="#{saClientcontroller.selectedSaClient.saClientAddress}" />
</h:panelGrid>
</p:dialog>
</f:view>
</h:body>
</html>
This is my Backing Bean.
public class SaClientController implements Serializable {
#EJB
private SaClientFacade saClientFacade;
private SaClient selectedSaClient;
private LazyDataModel<SaClient> lazyModel;
private List<SaClient> saclients;
/** Creates a new instance of SaClientController */
public SaClientController() {
}
#PostConstruct
public void Init() {
saclients = saClientFacade.Retrieve();
lazyModel = new LazyDataModelImp(saclients);
}
public LazyDataModel<SaClient> getLazyModel() {
return lazyModel;
}
public List<SaClient> getClients() {
return saClientFacade.Retrieve();
}
public SaClient getDetails() {
return selectedSaClient;
}
public String showDetails(SaClient selectedSaClient) {
this.selectedSaClient = selectedSaClient;
return "DETAILS";
}
public String update() {
System.out.println("###UPDATE###");
selectedSaClient = saClientFacade.Update(selectedSaClient);
return "SAVED";
}
public String list() {
System.out.println("###LIST###");
return "LIST";
}
public SaClient getSelectedSaClient() {
return selectedSaClient;
}
public void setSelectedSaClient(SaClient selectedSaClient) {
this.selectedSaClient = selectedSaClient;
}
public String dummyAction()
{
return null;
}
}
This is the LazyModelImp class
public class LazyDataModelImp extends LazyDataModel<SaClient> {
private List <SaClient> datasource;
public LazyDataModelImp(List<SaClient> datasource) {
this.datasource = datasource;
}
#Override
public SaClient getRowData(String rowKey) {
for (SaClient saclient : datasource) {
if (saclient.getIdSaClient().toString().equals(rowKey)) {
return saclient;
}
}
return null;
}
#Override
public Object getRowKey(SaClient saclient) {
return saclient.getIdSaClient().toString();
}
#Override
public List<SaClient> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
List<SaClient> data = new ArrayList<SaClient>();
//filter
for (SaClient saclient : datasource) {
boolean match = true;
for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = filters.get(filterProperty);
String fieldValue = String.valueOf(saclient.getFilterSortFieldValue(filterProperty));
if (filterValue == null || fieldValue.startsWith(filterValue.toUpperCase()) || fieldValue.startsWith(filterValue.toLowerCase())) {
match = true;
} else {
match = false;
break;
}
} catch (Exception e) {
match = false;
}
}
if (match) {
data.add(saclient);
}
}
//rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if (dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
} catch (IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else {
return data;
}
//sort
//if (sortField != null) {
// Collections.sort(data, new LazySorter(sortField, sortOrder));
//}
//return data;
}
}
I've already disabled the partial state saving in web.xml.
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
The backingBean is reinitialized the first time I click on the view detail commandButton in the last column of the dataTable in clienList.xhtml. And the dialog does not display at all. But after pressing F5. The dialog can be displayed but without any content, the only thing displayed in the dialog is the label outputText but not the bean values, they are empty. Sorry for newbie question. I will be extremely glad if anyone could advise what im doing is wrong, and maybe a little advise on the navigation and whether my strategy of displaying everything in index.xhtml (so I only have 1 view id all the time which is index.xhtml, right?) is right.
This may be the issue with your PrimeFaces dialog that you have an h:form surrounding the p:dialog. I have noticed the PrimeFaces dialog does not work properly when a child of a form element.
Try placing this dialog form inside of the contents of the dialog.
<p:dialog id="clientDialog" header="Client Detail" widgetVar="clientDialog" resizable="false" showEffect="explode" hideEffect="explode">
<h:form id="formdialog" prependId="false">
<h:panelGrid id="display" columns="2" cellpadding="4">
...

When adding a faces message in JSF my actions aren't performed?

I have the following backing bean:
#ViewScoped
#ManagedBean
public class WeighFamilyBacking2 implements Serializable {
private static final long serialVersionUID = 1L;
private String[] children = new String[] { "Child1", "Child2", "Child3" };
private HashMap<String, Integer> newWeights;
public WeighFamilyBacking2() {
newWeights = new HashMap<String, Integer>();
for (String s : getChildren())
newWeights.put(s, new Integer(0));
}
public void distributeWeightsWithoutMessage(ActionEvent event) {
for (String s : newWeights.keySet()) {
newWeights.put(s, newWeights.get(s) + 1);
}
}
public void distributeWeights(ActionEvent event) {
for (String s : newWeights.keySet()) {
newWeights.put(s, newWeights.get(s) + 1);
}
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Succesful", "Weights redistributed."));
}
public HashMap<String, Integer> getNewWeights() {
return newWeights;
}
public List<String> getChildren() {
return Arrays.asList(children);
}
}
... And the following xhtml 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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<h:form>
<ui:repeat var="child" value="#{weighFamilyBacking2.children}">
<h:outputText value="#{child}" />
<h:outputText value="#{weighFamilyBacking2.newWeights[child]}" /> -
<h:outputText value="#{weighFamilyBacking2.newWeights[child]}" /> -
<h:inputText id="oz" value="#{weighFamilyBacking2.newWeights[child]}" />
<h:inputText id="lbs"
value="#{weighFamilyBacking2.newWeights[child]}" />
<br />
</ui:repeat>
<h:commandButton
actionListener="#{weighFamilyBacking2.distributeWeights}"
value="Redistribute" />
<h:commandButton
actionListener="#{weighFamilyBacking2.distributeWeightsWithoutMessage}"
value="Redistribute Without Message" />
</h:form>
</h:body>
</html>
This is a simple reproducible test case. When you click on the redistribute without message, things work as expected. When you click on the redistribute button it displays the success message but the input fields are not updated. However, the text output field is updated just one time.
I have tried using immediate=true on both buttons and that doesn't affect this. This is a very simple case, I can't understand why it doesn't work.
I have tried this with all recent versions of Mojarra including 2.1.3.
This is another <ui:repeat> anomaly. I haven't nail down the exact root cause yet so that I can check if this is already reported to the JSF guys and if necessary report it, but I can tell that it works when I replace the <ui:repeat> by a <h:dataTable>.
<h:dataTable var="child" value="#{weighFamilyBacking2.children}">
<h:column>
<h:outputText value="#{child}" />
<h:outputText value="#{weighFamilyBacking2.newWeights[child]}" /> -
<h:outputText value="#{weighFamilyBacking2.newWeights[child]}" /> -
<h:inputText id="oz" value="#{weighFamilyBacking2.newWeights[child]}" />
<h:inputText id="lbs"
value="#{weighFamilyBacking2.newWeights[child]}" />
</h:column>
</h:dataTable>
Maybe a <table> is not semantically correct for you. If this is really undesireable, you might want to check if it works without problems with Tomahawk's <t:dataList>, RichFaces' <rich:dataList>, PrimeFaces' <p:dataList>, etc each which supports rendering the children without additional markup.
Update: I reported it as issue 2157.

Resources