Finally I’ve managed how to build a true dynamic table with the DOM-like approach in JSF when the data table structure is defined according to an external source. ( DataTable with dynamic columns exactly what I need) Basically, the following code is quite enough for me:
<p:layoutUnit position="west">
<!-- 2 -->
<p:tree value="#{tableViewsPageBean.root}" var="node" dynamic="true" cache="false"
selectionMode="single" selection="#{tableViewsPageBean.selectedNode}">
<!-- 3 -->
<p:ajax event="select" listener="#{tableViewsPageBean.onNodeSelect}"/>
<p:treeNode id="treeNode">
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:panelGroup>
<h:panelGroup rendered="#{tableViewsPageBean.isRegeneratable}">
<p:commandButton value="#{fu:$(languageBean, 'REGENERATE')}"
action="#{dynamicTableViewBean.regenerate}"/>
</h:panelGroup>
<!-- 1 -->
<h:panelGroup binding="#{dynamicTableViewBean.dataTableGroup}"/>
</h:panelGroup>
</p:layoutUnit>
But there is a problem I currently do not know how to solve. If you take a look at the code above, you can see the numeric markers in the comments that represent the flow of the backing beans methods:
binding="#{dynamicTableViewBean.dataTableGroup}"selection="#{tableViewsPageBean.selectedNode}"listener="#{tableViewsPageBean.onNodeSelect}"
This order is not good for me, because the binding of the h:panelGroup must be defined after a user changed the selection in the tree view. Simply saying, the very best flow would be:
selection="#{tableViewsPageBean.selectedNode}"(previously 2)listener="#{tableViewsPageBean.onNodeSelect}"(previously 3)binding="#{dynamicTableViewBean.dataTableGroup}"(previously 1)
so I could build a data table component respecting the user selection in the tree. So is it a way to force another order of executing the methods above? PrimeFaces version used: 3.2
Thanks in advance. Your help is appreciated a lot.
It worked that way in old JSF 1.x on JSP, but not anymore in JSF 2.x on Facelets. But the invocation order should not matter. Just make the
bindinggetter/setter a normal getter/setter and manipulate thedataTableGroupinside the listener method instead. It’s after all the same object reference.You only need to add the
updateattribute to<p:ajax>in order to really update the bound panelgroup or one of its parents when the ajax request completes, otherwise you will effectively see no change in the view.E.g.
By the way, are you aware of PrimeFaces’
<p:columns>component? It may be a better solution if all you want is dynamic columns. That solution didn’t exist in flavor of anyUIComponentback in the dark JSF 1.x ages, that’s why the awkwardbindingworkaround was been applied.