如何对所有选项卡 primefaces 使用相同的数据表(在这种情况下调整大小不起作用)
How to use the same datatable for all the tabs primefaces (resize not working in this case)
我正在使用 primefaces 5.3 和 jsf 2.2.6。
我创建了两个静态选项卡,看看它是否可以使用包含数据表的相同 xhtml 页面 (transactionsPage)。
这些是选项卡:
<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>
我使用了子视图,以便从包含的 transactionsPage.xhtml 中获得不同的数据表 ID,这样我就可以对所有选项卡使用相同的 xhtml 页面,并且只更改列和数据,即在transactionsPage.xhtml.
的托管bean中计算
所以对于数据表
从第一个选项卡开始:绝对路径为
formTabs:tabs:tab0:transactionsTable
从第二个选项卡:绝对路径是
formTabs:tabs:tab1:transactionsTable
这是来自交易页面的数据表:
<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>
问题如下:
当我想调整上次打开的选项卡中的列大小时,它起作用了,我看到在从托管 bean 调用调整大小方法之前,调用了 primefaces Datatable.class 中的 queueEvent 方法(在此方法决定调用哪个事件),其中 clientId 是正确的 formTabs:tabs:tab1:transactionsTable 然后调用调整大小方法。
但是当我进入另一个选项卡时,queueEvent 方法中的 clientId 保持不变,从最后一个选项卡 openend formTabs:tabs:tab1:transactionsTable 并且我得到以下异常,因此不再调用 resize 方法.
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)
我假设会发生这种情况,因为数据表的 clientId 未从选项卡更新到数据表,我已将焦点更改为该选项卡。
所以问题是:如何将整个 path/id 更改为新打开的 tab/datatable:
formTabs:tabs:tab0:transactionsTable
因为我的假设是,这就是为什么没有为另一个选项卡调用调整大小方法,然后是最后打开的选项卡。
如果说的不够清楚或者架构不好,那么问题就是
如何在不创建 11 个静态数据表的情况下对 11 个选项卡使用相同的 xhtml page/datatable?
所以,问题似乎出在数据表的 widgetVar 上,因为它为每个数据表的 widgetVar 使用了相同的值,这就是为什么它具有相同的 clientId,因为相同的 clientId 被添加到DOM.
如果您想阅读有关 widgetVar 的信息:
http://blog.hatemalimam.com/intro-to-primefaces-widgetvar/
因此,作为结论,我为每个选项卡的 widgetVar 动态设置了一个值,并且 primefaces 数据表中的 clientId class 是正确的,调用了 resize 方法并且它起作用了。
我正在使用 primefaces 5.3 和 jsf 2.2.6。
我创建了两个静态选项卡,看看它是否可以使用包含数据表的相同 xhtml 页面 (transactionsPage)。
这些是选项卡:
<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>
我使用了子视图,以便从包含的 transactionsPage.xhtml 中获得不同的数据表 ID,这样我就可以对所有选项卡使用相同的 xhtml 页面,并且只更改列和数据,即在transactionsPage.xhtml.
的托管bean中计算所以对于数据表 从第一个选项卡开始:绝对路径为
formTabs:tabs:tab0:transactionsTable
从第二个选项卡:绝对路径是
formTabs:tabs:tab1:transactionsTable
这是来自交易页面的数据表:
<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>
问题如下:
当我想调整上次打开的选项卡中的列大小时,它起作用了,我看到在从托管 bean 调用调整大小方法之前,调用了 primefaces Datatable.class 中的 queueEvent 方法(在此方法决定调用哪个事件),其中 clientId 是正确的 formTabs:tabs:tab1:transactionsTable 然后调用调整大小方法。
但是当我进入另一个选项卡时,queueEvent 方法中的 clientId 保持不变,从最后一个选项卡 openend formTabs:tabs:tab1:transactionsTable 并且我得到以下异常,因此不再调用 resize 方法.
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)
我假设会发生这种情况,因为数据表的 clientId 未从选项卡更新到数据表,我已将焦点更改为该选项卡。
所以问题是:如何将整个 path/id 更改为新打开的 tab/datatable:
formTabs:tabs:tab0:transactionsTable
因为我的假设是,这就是为什么没有为另一个选项卡调用调整大小方法,然后是最后打开的选项卡。
如果说的不够清楚或者架构不好,那么问题就是 如何在不创建 11 个静态数据表的情况下对 11 个选项卡使用相同的 xhtml page/datatable?
所以,问题似乎出在数据表的 widgetVar 上,因为它为每个数据表的 widgetVar 使用了相同的值,这就是为什么它具有相同的 clientId,因为相同的 clientId 被添加到DOM.
如果您想阅读有关 widgetVar 的信息: http://blog.hatemalimam.com/intro-to-primefaces-widgetvar/
因此,作为结论,我为每个选项卡的 widgetVar 动态设置了一个值,并且 primefaces 数据表中的 clientId class 是正确的,调用了 resize 方法并且它起作用了。