In my application I have a PF layout with a Tree node on west part, and a content part on center where I want to load different pages dynamically with ajax technology.
To get it, this content part contains an ui:include
tag with EL
expression. When the user clicks a tree node button, a page is rendered correctly on the center (and that works pretty well!). But some functionality of datatable such as sorting is broken or lost.
Moreover, if a refresh completely the page from the web browser all works OK.
I have simplified my project in order to give you a clean example.
The index.xhtml
:
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" header="Top">
</p:layoutUnit>
<p:layoutUnit position="west" size="100" resizable="true">
<h:form>
<p:tree id="menuTree"
value="#{menuController.root}"
var="node"
selection="#{menuController.selectedNode}"
selectionMode="single">
<p:ajax event="select" update=":content" listener="#{menuController.setPage(node)}" />
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="east" size="50"/>
<p:layoutUnit position="south" size="60"/>
<p:layoutUnit position="center" id="centerlayout">
<h:panelGroup id="content">
<c:if test="${not empty menuController.page}">
<ui:include src="#{menuController.page}.xhtml" />
</c:if>
</h:panelGroup>
</p:layoutUnit>
</p:layout>
</h:body>
I would like to remark that I've tried to change the ui:include
with EL
and use the conditional render of a container h:panelGroup
and an static ui:include
, but the problem persist.
The backing bean of Tree menu:
@Named
@SessionScoped
public class MenuController implements Serializable {
private TreeNode root;
private TreeNode selectedNode;
private String pageName;
public MenuController() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node00 = new DefaultTreeNode("/list", node0);
TreeNode node01 = new DefaultTreeNode("/list2", node0);
}
public TreeNode getRoot() {
return root;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void setPage(String page){
this.pageName = page;
}
public String getPage(){
return this.pageName;
}
The page that contains data table list.xhtml
(note that list2.xhtml
is equal, changing some text to 'watch' the content update):
<ui:composition>
<h:form id="ItemListForm">
<p:panel header="Title">
<p:dataTable id="datalist" value="#{itemController.items}" var="item"
selectionMode="single" selection="#{itemController.selected}"
rowKey="#{item.itemid}"
paginator="true"
rows="10"
rowsPerPageTemplate="10,20,30" >
<p:column sortBy="#{item.itemid}" filterBy="#{item.itemid}">
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value="#{item.itemid}"/>
</p:column>
<p:column sortBy="#{item.productid}" filterBy="#{item.productid}">
<f:facet name="header">
<h:outputText value="ProductId"/>
</f:facet>
<h:outputText value="#{item.productid}"/>
</p:column>
<p:column sortBy="#{item.name}" filterBy="#{item.name}">
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column sortBy="#{item.description}" filterBy="#{item.description}">
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:outputText value="#{item.description}"/>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
The ItemController
bean:
@Named
@SessionScoped
public class ItemController implements Serializable {
private Item selected;
private List<Item> items;
public ItemController() {
this.items = new ArrayList<>();
this.items.add(new Item("1", "1", "Product 1", "testing sorting"));
this.items.add(new Item("3", "3", "Product 3", "testing sorting"));
this.items.add(new Item("2", "2", "Product 2", "testing sorting"));
this.items.add(new Item("4", "4", "Product 4", "testing sorting"));
this.items.add(new Item("5", "5", "Product 5", "testing sorting"));
this.items.add(new Item("6", "6", "Product 6", "testing sorting"));
}
public Item getSelected() {
return selected;
}
public void setSelected(Item selected) {
this.selected = selected;
}
public List<Item> getItems() {
return items;
}
The class Item
, very simple:
public class Item implements Serializable {
private String itemid;
private String productid;
private String name;
private String description;
public Item() {
}
public Item(String itemid) {
this.itemid = itemid;
}
public Item(String itemid, String productid, String name, String description) {
this.itemid = itemid;
this.productid = productid;
this.name = name;
this.description = description;
}
public String getItemid() {
return itemid;
}
public void setItemid(String itemid) {
this.itemid = itemid;
}
public String getProductid() {
return productid;
}
public void setProductid(String productid) {
this.productid = productid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
Finally, I'm working with:
Java EE 7
PrimeFaces 3.5 Community
JSF 2.2
Glassfish 4
NetBeans 7.3.1
Safari browser