How to use the same datatable for all the tabs primefaces (resize not working in this case)

跟風遠走 提交于 2019-12-12 01:24:42

问题


I am using primefaces 5.3 and jsf 2.2.6.

I have created two static tabs to see if it works to use the same xhtml page (transactionsPage) that contains a datatable.

These are the tabs:

    <h:form id="formTabs">
      <p:tabView id="tabs" activeIndex="#{mainPage.index}">
        <p:ajax event="tabClose" listener="#{mainPage.remove}" update="formTabs" />
        <p:ajax event="tabChange" listener="#{mainPage.changeTab}" update="formTabs" />
            <p:tab id="transAssembling" title="ASSEMBLING" closable="true">
                <f:subview id="tab0">   
                    <ui:include src="transactionsPage.xhtml">
                        <ui:param name="status" value="ASSEMBLING" />
                        <ui:param name="columnList" value="#{tabs.list[0].columnList}" />
                    </ui:include>
                </f:subview>
            </p:tab>

            <p:tab id="transPrinting" title="PRINTING" closable="true">
                <f:subview id="tab1">
                    <ui:include src="transactionsPage.xhtml">
                        <ui:param name="status" value="PRINTING" />
                        <ui:param name="columnList" value="#{tabs.list[1].columnList}" />
                    </ui:include>
                </f:subview>
            </p:tab>
     </p:tabView>
</h:form>

I used the subView, in order to have different ids for the datatable from the included transactionsPage.xhtml, so that I can use the same xhtml page for all tabs and only change the columns and data, that are calculated in the managed bean of the transactionsPage.xhtml.

So for the datatable from the first tab: the absolute path would be

formTabs:tabs:tab0:transactionsTable

from the second tab: the absolute path would be

formTabs:tabs:tab1:transactionsTable

This is the datatable from the transactionsPage:

<p:dataTable id="transactionsTable" var="data" value="#{transactionsPage.ttList}" widgetVar="projectData" 
                     rowKey="#{data.id}"
                     draggableColumns="true" 
                     draggableRows="true"
                     resizableColumns="true" emptyMessage="#{msg['form.noTransactionsFound']}" rows="20"
                     selectionMode="single" selection="#{transactionsPage.selectedTransaction}"
                     filteredValue="#{transactionsPage.fitleredttList}" paginator="true" paginatorPosition="both" paginatorTemplate="{CurrentPageReport} {RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
                     >

            <p:ajax event="colResize" listener="#{transactionsPage.onColumnResize}" update="transactionsTable"/>

            <f:ajax event="rowSelect" render="formTabs"/>
            <!-- Stiky does not work with column filtering paginator="true" paginatorPosition="bottom" paginatorTemplate="{CurrentPageReport} {RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} " stickyHeader="true" -->

            <f:facet name="header">
                <p:outputPanel styleClass="mainPageProjectsTableHeader" >
                    <h:outputText value="#{msg['form.searchAllFields']}" style="float:left; margin-right:10px;"/>
                    <p:inputText id="globalFilter" onkeyup="PF('projectData').filter()" style="width:150px; float:left" placeholder=" #{msg['form.enterKeyword']}"/>

                    <p:commandButton id="toggler" type="button" value="#{msg['form.columns']}" 
                            styleClass="columnSelector" icon="ui-icon-calculator" />
                    <p:columnToggler datasource="transactionsTable" trigger="toggler" >
                        <p:ajax event="toggle" listener="#{transactionsPage.onToggle}" />
                    </p:columnToggler>
                </p:outputPanel>
            </f:facet>

            <c:forEach var="column" items="#{transactionsPage.columnList}">
                <p:column id="#{column.id}" filterStyleClass="#{column.filterStyleClass}" headerText="#{column.title}" visible="#{column.visible}" width="#{column.width}" filterBy="#{data[column.property]}" filterMatchMode="contains" styleClass="mainPageCompanyColumn">
                    <f:attribute name="rtcCol" value="#{column}"/>
                    <h:outputText value="#{data[column.property]}" />
                </p:column>
            </c:forEach>

        </p:dataTable>

The problem is the following:

When I want to resize a column in the last opened tab, it works and I see that before calling the resize method from the managed bean, a queueEvent method from the primefaces Datatable.class is called(in this method it takes the decision which event to call), in which the clientId is correct formTabs:tabs:tab1:transactionsTable and then the resize method is being called.

But when I go in another tab, the clientId from the queueEvent method remains the same, from the last tab openend formTabs:tabs:tab1:transactionsTable and I get the following exception, so that the resize method is not be called anymore.

 java.lang.NullPointerException
at org.primefaces.component.datatable.DataTable.findColumnInGroup(DataTable.java:909)
at org.primefaces.component.datatable.DataTable.findColumn(DataTable.java:900)
at org.primefaces.component.datatable.DataTable.queueEvent(DataTable.java:814)
at org.primefaces.behavior.ajax.AjaxBehaviorRenderer.decode(AjaxBehaviorRenderer.java:47)
at javax.faces.component.behavior.ClientBehaviorBase.decode(ClientBehaviorBase.java:132)
at org.primefaces.renderkit.CoreRenderer.decodeBehaviors(CoreRenderer.java:530)
at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:66)

I assume this happens, because of the clientId of the datatable, which is not updated to the datatable from the tab, where I have changed the focus on.

So the question would be: How could I change the whole path/id to the newly opened tab/datatable:

formTabs:tabs:tab0:transactionsTable

because my assumption is that that's why the resize method is not being called for another tab then the last opened tab.

If it's not clear enough or the architecture is bad, then the question would be How to use the same xhtml page/datatable for 11 tabs without creating 11 static datatables?


回答1:


So, it seemed that the problem was the widgetVar from the datatable, because it was used the same value for the widgetVar for every single datatable and that's why it had the same clientId, because the same clientId was added to the DOM.

If you want to read about the widgetVar: http://blog.hatemalimam.com/intro-to-primefaces-widgetvar/

So, as a conclusion, I have set dynamically a value to the widgetVar for each tab and the clientId in the primefaces Datatable class was correct,the resize method was called and it worked.



来源:https://stackoverflow.com/questions/36284870/how-to-use-the-same-datatable-for-all-the-tabs-primefaces-resize-not-working-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!