我在Wildfly 8.0.0上使用Primefaces 5和Primefaces Extension 2.0.0以及JSF 2.2。
我使用freezeColumns,过滤,分页以及内置复选框提供的多选来实现数据表。
在大多数情况下,会提交所选项目,但不会在以下示例中提交:
我的数据表的xhtml
<h:form id="jobListForm">
<p:panelGrid columns="2" styleClass="no-border">
</p:panelGrid>
<p:panelGrid columns="2" styleClass="no-border">
<p:selectBooleanCheckbox id="showAllTenants" value="#{JobProtocolBean.showAllTenants}" rendered="#{TenantController.isSuperAdmin}">
<p:ajax listener="#{FacesController.refresh}" event="change"/>
</p:selectBooleanCheckbox>
<p:outputLabel for="showAllTenants" value="Show all tenants" rendered="#{TenantController.isSuperAdmin}"/>
</p:panelGrid>
<h:panelGroup>
<mx:tableControls managedBean="#{JobProtocolBean}" />
<p:commandButton icon="ui-icon-arrowreturnthick-1-s" action="#{JobProtocolBean.showExportDialog}" value="Export" ajax="false" rendered="#{Shiro.isPermitted('jobprotocol:list:xmlexport')}" />
<p:dataTable id="JobProtocolTable" widgetVar="JobProtocolTableVar" value="#{JobProtocolBean.items}" binding="#{JobProtocolBean.items.dataTable}" lazy="true"
filteredValue="#{JobProtocolBean.filter}" var="item" paginator="true" rows="10"
currentPageReportTemplate="(Displaying results {startRecord} - {endRecord} of {totalRecords})"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,20,50,100,200,500,1000" filterEvent="enter"
selection="#{JobProtocolBean.selectedJobProtocols}"
scrollable="true" scrollWidth="50%" scrollHeight="100%" frozenColumns="2">
<f:event type="preRenderComponent" listener="#{JobProtocolBean.items.preRenderComponent}" />
<p:column id="ACTIONS" headerText="Actions" width="120">
<p:panelGrid columns="4" styleClass="button-column">
<p:commandButton icon="ui-icon-info" action="#{JobProtocolBean.startDetail}" ajax="false" title="Detail" disabled="#{not Shiro.isPermitted('jobprotocol:list:detail')}"/>
<p:commandButton icon="ui-icon-pencil" action="#{JobProtocolBean.startEdit}" ajax="false" title="Edit" disabled="#{not (Shiro.isPermitted('jobprotocol:list:edit') and (item.stateSkipped or item.stateUnplanned))}" />
<p:commandButton icon="ui-icon-copy" action="#{JobProtocolBean.startCopy}" ajax="false" title="Copy" disabled="#{not (Shiro.isPermitted('jobprotocol:list:retry') and item.stateDone and item.cron eq 'onetime')}" rendered="#{item.stateDone}" />
<p:commandButton icon="ui-icon-arrowrefresh-1-e" action="#{JobProtocolBean.startRetry}" ajax="false" title="Retry" disabled="#{not (Shiro.isPermitted('jobprotocol:list:retry') and item.stateSkipped)}" rendered="#{not (item.stateDone or item.stateQueued or item.stateUnplanned or item.statePlanned)}" />
<p:commandButton icon="ui-icon-pause" action="#{JobProtocolBean.startSuspend}" ajax="false" title="Suspend" onclick="return confirm('Do you really want to suspend this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:suspend')}" rendered="#{item.statePlanned}" />
<p:commandButton icon="ui-icon-play" action="#{JobProtocolBean.startResume}" ajax="false" title="Resume" onclick="return confirm('Do you really want to resume this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:resume')}" rendered="#{item.stateUnplanned}" />
<p:commandButton icon="ui-icon-circle-minus" action="#{JobProtocolBean.startUnqueue}" ajax="false" title="Unqueue" onclick="return confirm('Do you really want to unqueue and re-schedule this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:unqueue')}" rendered="#{item.stateQueued}" />
<p:commandButton icon="ui-icon-cancel" action="#{JobProtocolBean.startSkip}" ajax="false" title="Skip" disabled="#{not Shiro.isPermitted('jobprotocol:list:skip') or item.stateDoneOrSkipped}" />
</p:panelGrid>
</p:column>
<p:column selectionMode="multiple" width="18" />
<p:column id="ID" headerText="ID" sortBy="#{item.id}" filterBy="#{item.id}" width="50">
<h:outputText title="#{item.id}" value="#{item.id}"/>
</p:column>
<p:column id="TENANT" headerText="Tenant" rendered="#{JobProtocolBean.showAllTenants}" sortBy="#{item.tenantId}" filterBy="#{item.tenantId}" width="50">
<h:outputText title="#{item.tenantId}" value="#{item.tenantId}" converter="JobTenantConverter"/>
</p:column>
<p:column id="INITIATOR" headerText="Initiator" sortBy="#{item.initiator}" filterBy="#{item.initiator}" width="120">
<h:outputText title="#{item.initiator}" value="#{item.initiator}" />
</p:column>
<p:column id="CODE" headerText="Code" sortBy="#{item.code}" filterBy="#{item.code}" width="300">
<h:outputText title="#{item.code}" value="#{item.code}" converter="JobCodeConverter" escape="false" />
</p:column>
<p:column id="CHANNEL_ID" headerText="Channel ID" sortBy="#{item.channelId}" filterBy="#{item.channelId}" width="150">
<h:outputText title="#{item.channel}" value="#{item.channel}" />
</p:column>
<p:column id="SEQUENCE" headerText="Sequence" sortBy="#{item.orderId}" filterBy="#{item.orderId}" width="65" >
<h:outputText title="#{item.orderId}" value="#{item.orderId}" />
</p:column>
<p:column id="STATE" headerText="State" filterBy="#{item.state}" filterOptions="#{JobProtocolBean.states}" width="80">
<h:outputText value="#{item}" converter="JobStateConverter" />
</p:column>
<p:column id="CRON" headerText="Cron" sortBy="#{item.cron}" filterBy="#{item.cron}" width="70" >
<h:outputText title="#{item.cron}" value="#{item.cron}" />
</p:column>
<p:column id="META" headerText="Meta" sortBy="#{item.meta}" filterBy="#{item.meta}" width="100">
<h:outputText title="#{item.meta}" value="#{item.meta}" />
</p:column>
<p:column id="MIN_FAILURES" headerText="≥ Retries" sortBy="#{item.failures}" filterBy="#{item.failures}" width="60">
<h:outputText title="#{item.failures}" value="#{item.failures}" />
</p:column>
<p:column id="BUSINESS_ERROR" headerText="Failure" sortBy="#{item.errorCode}" filterBy="#{item.errorCode}" width="80">
<h:outputText title="#{item.errorCode}" value="#{item.errorCode}" />
</p:column>
<p:column id="SKIP_REASON" headerText="Skip Reason" sortBy="#{item.skipReason}" filterBy="#{item.skipReason}" width="80">
<h:outputText title="#{item.skipReason}" value="#{item.skipReason}" />
</p:column>
<p:column id="TIME_STORED" sortBy="#{item.timeStored}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeStored}" datePropertyName="timeStored" headerText="Time Stored" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="PLANNED_START" sortBy="#{item.nextPlannedStart}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.nextPlannedStart}" datePropertyName="nextPlannedStart" headerText="Planned Start" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_QUEUED" sortBy="#{item.timeQueued}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeQueued}" datePropertyName="timeQueued" headerText="Time Queued" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_STARTED" sortBy="#{item.timeStarted}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeStarted}" datePropertyName="timeStarted" headerText="Time Started" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_DONE" sortBy="#{item.timeDone}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeDone}" datePropertyName="timeDone" headerText="Time Done" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
</p:dataTable>
<p:outputPanel styleClass="ui-paginator-inline-span">
<p:selectOneMenu id="ACTION_SELECTOR" value="#{JobProtocolBean.selectedAction}" >
<f:selectItems value="#{JobProtocolBean.accessibleActions}" itemValue="#{JobProtocolBean.accessibleActions.value}" />
</p:selectOneMenu>
<p:commandButton id="ACTION_BUTTON" action="#{JobProtocolBean.startActionSelected}" ajax="false" value="OK" />
</p:outputPanel>
<mxtaglib:blockUI block="JobProtocolTable" trigger="JobProtocolTable" styleClass="block-ui" />
</h:panelGroup>
</h:form>
<h:form id="jobListForm">
<p:panelGrid columns="2" styleClass="no-border">
</p:panelGrid>
<p:panelGrid columns="2" styleClass="no-border">
<p:selectBooleanCheckbox id="showAllTenants" value="#{JobProtocolBean.showAllTenants}" rendered="#{TenantController.isSuperAdmin}">
<p:ajax listener="#{FacesController.refresh}" event="change"/>
</p:selectBooleanCheckbox>
<p:outputLabel for="showAllTenants" value="Show all tenants" rendered="#{TenantController.isSuperAdmin}"/>
</p:panelGrid>
<h:panelGroup>
<mx:tableControls managedBean="#{JobProtocolBean}" />
<p:commandButton icon="ui-icon-arrowreturnthick-1-s" action="#{JobProtocolBean.showExportDialog}" value="Export" ajax="false" rendered="#{Shiro.isPermitted('jobprotocol:list:xmlexport')}" />
<p:dataTable id="JobProtocolTable" widgetVar="JobProtocolTableVar" value="#{JobProtocolBean.items}" binding="#{JobProtocolBean.items.dataTable}" lazy="true"
filteredValue="#{JobProtocolBean.filter}" var="item" paginator="true" rows="10"
currentPageReportTemplate="(Displaying results {startRecord} - {endRecord} of {totalRecords})"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,20,50,100,200,500,1000" filterEvent="enter"
selection="#{JobProtocolBean.selectedJobProtocols}"
scrollable="true" scrollWidth="50%" scrollHeight="100%" frozenColumns="2">
<f:event type="preRenderComponent" listener="#{JobProtocolBean.items.preRenderComponent}" />
<p:column id="ACTIONS" headerText="Actions" width="120">
<p:panelGrid columns="4" styleClass="button-column">
<p:commandButton icon="ui-icon-info" action="#{JobProtocolBean.startDetail}" ajax="false" title="Detail" disabled="#{not Shiro.isPermitted('jobprotocol:list:detail')}"/>
<p:commandButton icon="ui-icon-pencil" action="#{JobProtocolBean.startEdit}" ajax="false" title="Edit" disabled="#{not (Shiro.isPermitted('jobprotocol:list:edit') and (item.stateSkipped or item.stateUnplanned))}" />
<p:commandButton icon="ui-icon-copy" action="#{JobProtocolBean.startCopy}" ajax="false" title="Copy" disabled="#{not (Shiro.isPermitted('jobprotocol:list:retry') and item.stateDone and item.cron eq 'onetime')}" rendered="#{item.stateDone}" />
<p:commandButton icon="ui-icon-arrowrefresh-1-e" action="#{JobProtocolBean.startRetry}" ajax="false" title="Retry" disabled="#{not (Shiro.isPermitted('jobprotocol:list:retry') and item.stateSkipped)}" rendered="#{not (item.stateDone or item.stateQueued or item.stateUnplanned or item.statePlanned)}" />
<p:commandButton icon="ui-icon-pause" action="#{JobProtocolBean.startSuspend}" ajax="false" title="Suspend" onclick="return confirm('Do you really want to suspend this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:suspend')}" rendered="#{item.statePlanned}" />
<p:commandButton icon="ui-icon-play" action="#{JobProtocolBean.startResume}" ajax="false" title="Resume" onclick="return confirm('Do you really want to resume this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:resume')}" rendered="#{item.stateUnplanned}" />
<p:commandButton icon="ui-icon-circle-minus" action="#{JobProtocolBean.startUnqueue}" ajax="false" title="Unqueue" onclick="return confirm('Do you really want to unqueue and re-schedule this job?');" disabled="#{not Shiro.isPermitted('jobprotocol:list:unqueue')}" rendered="#{item.stateQueued}" />
<p:commandButton icon="ui-icon-cancel" action="#{JobProtocolBean.startSkip}" ajax="false" title="Skip" disabled="#{not Shiro.isPermitted('jobprotocol:list:skip') or item.stateDoneOrSkipped}" />
</p:panelGrid>
</p:column>
<p:column selectionMode="multiple" width="18" />
<p:column id="ID" headerText="ID" sortBy="#{item.id}" filterBy="#{item.id}" width="50">
<h:outputText title="#{item.id}" value="#{item.id}"/>
</p:column>
<p:column id="TENANT" headerText="Tenant" rendered="#{JobProtocolBean.showAllTenants}" sortBy="#{item.tenantId}" filterBy="#{item.tenantId}" width="50">
<h:outputText title="#{item.tenantId}" value="#{item.tenantId}" converter="JobTenantConverter"/>
</p:column>
<p:column id="INITIATOR" headerText="Initiator" sortBy="#{item.initiator}" filterBy="#{item.initiator}" width="120">
<h:outputText title="#{item.initiator}" value="#{item.initiator}" />
</p:column>
<p:column id="CODE" headerText="Code" sortBy="#{item.code}" filterBy="#{item.code}" width="300">
<h:outputText title="#{item.code}" value="#{item.code}" converter="JobCodeConverter" escape="false" />
</p:column>
<p:column id="CHANNEL_ID" headerText="Channel ID" sortBy="#{item.channelId}" filterBy="#{item.channelId}" width="150">
<h:outputText title="#{item.channel}" value="#{item.channel}" />
</p:column>
<p:column id="SEQUENCE" headerText="Sequence" sortBy="#{item.orderId}" filterBy="#{item.orderId}" width="65" >
<h:outputText title="#{item.orderId}" value="#{item.orderId}" />
</p:column>
<p:column id="STATE" headerText="State" filterBy="#{item.state}" filterOptions="#{JobProtocolBean.states}" width="80">
<h:outputText value="#{item}" converter="JobStateConverter" />
</p:column>
<p:column id="CRON" headerText="Cron" sortBy="#{item.cron}" filterBy="#{item.cron}" width="70" >
<h:outputText title="#{item.cron}" value="#{item.cron}" />
</p:column>
<p:column id="META" headerText="Meta" sortBy="#{item.meta}" filterBy="#{item.meta}" width="100">
<h:outputText title="#{item.meta}" value="#{item.meta}" />
</p:column>
<p:column id="MIN_FAILURES" headerText="≥ Retries" sortBy="#{item.failures}" filterBy="#{item.failures}" width="60">
<h:outputText title="#{item.failures}" value="#{item.failures}" />
</p:column>
<p:column id="BUSINESS_ERROR" headerText="Failure" sortBy="#{item.errorCode}" filterBy="#{item.errorCode}" width="80">
<h:outputText title="#{item.errorCode}" value="#{item.errorCode}" />
</p:column>
<p:column id="SKIP_REASON" headerText="Skip Reason" sortBy="#{item.skipReason}" filterBy="#{item.skipReason}" width="80">
<h:outputText title="#{item.skipReason}" value="#{item.skipReason}" />
</p:column>
<p:column id="TIME_STORED" sortBy="#{item.timeStored}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeStored}" datePropertyName="timeStored" headerText="Time Stored" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="PLANNED_START" sortBy="#{item.nextPlannedStart}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.nextPlannedStart}" datePropertyName="nextPlannedStart" headerText="Planned Start" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_QUEUED" sortBy="#{item.timeQueued}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeQueued}" datePropertyName="timeQueued" headerText="Time Queued" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_STARTED" sortBy="#{item.timeStarted}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeStarted}" datePropertyName="timeStarted" headerText="Time Started" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
<p:column id="TIME_DONE" sortBy="#{item.timeDone}" width="120">
<mxtaglib:dateFilter dateProperty="#{item.timeDone}" datePropertyName="timeDone" headerText="Time Done" tableBinding="#{JobProtocolBean.items}"/>
</p:column>
</p:dataTable>
<p:outputPanel styleClass="ui-paginator-inline-span">
<p:selectOneMenu id="ACTION_SELECTOR" value="#{JobProtocolBean.selectedAction}" >
<f:selectItems value="#{JobProtocolBean.accessibleActions}" itemValue="#{JobProtocolBean.accessibleActions.value}" />
</p:selectOneMenu>
<p:commandButton id="ACTION_BUTTON" action="#{JobProtocolBean.startActionSelected}" ajax="false" value="OK" />
</p:outputPanel>
<mxtaglib:blockUI block="JobProtocolTable" trigger="JobProtocolTable" styleClass="block-ui" />
</h:panelGroup>
</h:form>
答案 0 :(得分:0)
我找到了所描述错误的起源: 带有frozenColumns的数据表的Javascript对象提供了一个函数来复制ajax请求所带来的,如sort,filter等。 此函数不处理保存在数据(jQuery data())中的'rk'值。
原件:
copyRow: function(original) {
return $('<tr></tr>').data('ri', original.data('ri')).addClass(original.attr('class')).attr('role', 'row');
};
我的解决方法:
PF(datatableUtils.datatableWidgetVar).copyRow = function(original) {
return $('<tr></tr>').attr('data-ri', original.data('ri')).attr('data-rk', original.data('rk')).addClass(original.attr('class')).attr('role', 'row');
};
使用attr()和'data-'前缀写入数据是必要的,因为它似乎丢失了存储的数据,因为tr尚未附加。 (老实说,如果我错了,请纠正我)