Using on the template page in JSF
I have a DataTable (Primefaces 3.5, JSF 2.0) which is populated from a
database. In the first column of this table, checkboxes are displayed
(multiple row selection).
After selecting row(s), when a button (<p:commandButton>) is pressed, the
selected rows are expected to be deleted from the database.
Before deleting row(s), a confirm message regarding the deletion of the
selected row(s) is displayed in <p:confirmDialog> with two buttons Yes and
No something like the following.
Test.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">
<ui:composition template="template/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="title">Test</ui:define>
<ui:define name="content">
<h:head>
<title>Test</title>
</h:head>
<h:form id="form">
<p:dataTable id="dataTable" var="row"
value="#{testManagedBean.list}"
selection="#{testManagedBean.selectedValues}"
rowKey="#{row.id}"
rowIndexVar="rowIndex">
<p:column selectionMode="multiple" style="width:5%;
text-align: center;">
<f:facet name="footer">
----------------> <p:commandButton
actionListener="#{testManagedBean.deleteMultipleActionListener}"
oncomplete="confirmDeleteMultiple.show()"
update=":form:confirmDialogDeleteMultiple" process=":form:dataTable"
icon="ui-icon ui-icon-close"/>
</f:facet>
</p:column>
<p:column headerText="Index">
<h:outputText value="#{rowIndex+1}"/>
</p:column>
<p:column id="id" headerText="Id">
<h:outputText value="#{row.id}"/>
</p:column>
<p:column id="countryName" headerText="Description">
<h:outputText value="#{row.description}"/>
</p:column>
</p:dataTable>
---------------><p:confirmDialog id="confirmDialogDeleteMultiple"
widgetVar="confirmDeleteMultiple" appendToBody="true" message="Delete
row(s)?" showEffect="true" hideEffect="true" header="Deletion of row."
severity="alert" closeOnEscape="true" closable="true">
<p:commandButton id="confirmDeleteMultiple"
value="Yes" oncomplete="confirmDeleteMultiple.hide()"
actionListener="#{testManagedBean.deleteMultiple}"
process="@this dataTable" update="dataTable"/>
<p:commandButton id="declineDeleteMultiple" value="No"
onclick="confirmDeleteMultiple.hide()" type="button"
/>
</p:confirmDialog>
</h:form>
</ui:define>
</ui:composition>
The managed bean:
@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable
{
@EJB(mappedName="ejb/JNDI")
private transient TestService testService;
private List<Test> list;
private List<Test>selectedValues;
public TestManagedBean(){}
@PostConstruct
public void init()
{
list=testService.getList();
}
public List<Test> getList() {
return list;
}
public List<Test> getSelectedValues() {
return selectedValues;
}
public void setSelectedValues(List<Test> selectedValues) {
this.selectedValues = selectedValues;
}
public void deleteMultipleActionListener(ActionEvent actionEvent)
{
//Just show a warning message, when the delete button is pressed.
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//Displays the list.
}
public void deleteMultiple(ActionEvent actionEvent)
{
System.out.println("multiple");
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//The list is not null and empty.
}
}
When the button (indicated by an arrow in XHTML) is pressed, the
deleteMultipleActionListener() method in the managed bean is invoked where
it simply displays the list which is populated by the selected rows and
the confirm dialog as shown in XHTML appears afterwards. (This is just to
show a warning message before deletion. The loop in this method is just
for the demonstration).
When the Yes button on the confirm dialog is pressed, the deleteMultiple()
method is invoked which is responsible for actual deletion of rows
(actionListioner in <p:commandButton> inside <p:confirmDialog>) and the
deletion of rows should be performed but here the list of the selected
rows retrieved here is empty (not null).
The resulting list inside the deleteMultiple() method is empty because of
<f:view> on the template page. The template page is shown below.
<?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 lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
--------->
<f:view locale="#{localeBean.locale}" encoding="UTF-8"
contentType="text/html">
<f:loadBundle basename="messages.ResourceBundle" var="messages"/>
<h:head><title><ui:insert name="title">Default
Title</ui:insert></title></h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="135" collapsed="false"
resizable="false" closable="false" collapsible="false"
gutter="6">
<h:form>
<h:selectOneMenu id="languages"
value="#{localeBean.language}" onchange="submit();"
style="position: absolute; right: 0; top: 50px;">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</h:selectOneMenu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="west" id="leftPanel" size="225"
header="Menu Item" resizable="false" closable="false"
collapsible="true" gutter="6">
</p:layoutUnit>
<p:layoutUnit position="center" size="2500" maxSize="2500">
<ui:insert name="content">Put default content here, if
any.</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
When I remove this template from the above Test.xhtml page and use this
<f:view> tag on the Test.xhtml page itself, everything works fine and the
list of the selected rows inside the deleteMultiple() method is obtained
correctly.
So, what is going wrong? Why does the list become empty when the Yes
button is pressed, if the template page is enclosed by <f:view>? Is it
wrong? How to accomplish this? (<f:view> is used for the localization of
the application as it can be imagined).
No comments:
Post a Comment