Search code examples
jsfdynamicjsf-2datatable

Dynamic Column in JSF Datatable JSF2.0


I need one help from you. I am using JSF 2.0 and I have a datatable component . One of the column in the datatable is an action column and I need to create a toolbar which contains different type of actionsource component such as command button, link etc. The type of actionsource is determined at run time and number of actionsource is also done at run time. How I can implement this in JSF 2.0

           <p:dataTable value="#{listBranchBean1.rowDataModel}" var="rowItem"
              id="myId" paginator="true"
              paginatorTemplate="{FirstPageLink}{PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}{RowsPerPageDropdown} "
              rowsPerPageTemplate="10,5,2" previousPageLinkLabel="&lt;"
              nextPageLinkLabel="&gt;" widgetVar="branchTable"
              selection="#{listBranchBean1.selectedBranchesPrime}"
              resizableColumns="true"
              sortBy="#{rowItem.columnsValueMap['branchId'].value}">
              <f:facet name="header">
                 <p:outputPanel>
                    <h:outputText value="Search all fields:" />
                    <p:inputText id="globalFilter" onkeyup="branchTable.filter()"
                       style="width:150px" />
                 </p:outputPanel>
              </f:facet>
              <p:column selectionMode="multiple" style="text-align:left">
                 <f:facet name="header">
                    <h:outputText value="Select" />
                 </f:facet>
                 <h:outputText value="#{rowItem.uniqueId}" />
              </p:column>
              <p:column
                 rendered="#{listBranchBean1.columnsMap['objectId'].hidden==false}"
                 sortBy="#{rowItem.columnsValueMap['objectId'].value}"
                 filterBy="#{rowItem.columnsValueMap['objectId'].value}">
                 <f:facet name="header">
                    <h:outputText
                       value="#{listBranchBean1.columnsMap['objectId'].displayLabel}" />
                 </f:facet>
                 <h:outputText
                    value="#{rowItem.columnsValueMap['objectId'].value}" />
              </p:column>
              <p:column
                 rendered="#{listBranchBean1.columnsMap['actions'].hidden==false}">
                 <f:facet name="header">
                    <h:outputText
                       value="#{listBranchBean1.columnsMap['actions'].displayLabel}" />
                 </f:facet>
                 <p:toolbar>
                    <p:toolbarGroup>
                       <ui:repeat var="action"
                          value="#{rowItem.columnsValueMap['actions'].value}">
                          <p:commandButton title="#{action}" type="button">
                          </p:commandButton>
                       </ui:repeat>
                    </p:toolbarGroup>

                 </p:toolbar>
              </p:column>
           </p:dataTable>

I want to replace the last column with something like

                 <p:toolbar binding="#{listBranchBean1.getActions(rowItem)}">
                 </p:toolbar>

I appreciate your help

Prajeesh Nair


Solution

  • There is a difference between build-time and render-time in JSF. Build-time tags like <ui:repeat> have the ability to create new components dynamically, but they can only use data that is available at build-time.

    However, using Java you are also allowed to alter the component tree programmatically, but this too can not just happen at any moment. The safe moment to do this is the preRenderViewEvent, which is a good bit later than the build-time moment (which is the restore view phase) and you should have all the data you need by then.

    Inside an event handler for this event you can reference the tool bar you bound to your backing bean, and programmatically add columns to it.

    For examples see:

    Do note that if your backing bean is @ViewScoped, you'd better not use binding but use a manual lookup instead. This is due to some bugs with respect to the view scope and binding components in JSF.