【问题标题】:Primefaces 5 Checkbox Multiselect Bug after Filtering过滤后的 Primefaces 5 复选框多选错误
【发布时间】:2014-09-03 20:26:11
【问题描述】:

我在 Wildfly 8.0.0 上使用 Primefaces 5 和 Primefaces Extension 2.0.0 和 JSF 2.2。

我使用frozenColumns、过滤、分页以及内置复选框提供的多选实现了一个数据表。

在大多数情况下,Selected Items 已提交,但在以下示例中不提交:

  1. 未选择任何项目
  2. 使用任何过滤器字段过滤数据表内容
  3. 选择项目
  4. 提交表格 -> 未提交所选项目

图片提供于the primefaces Forum

我的数据表的 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="&#8805; 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>

【问题讨论】:

  • 添加rowKey属性有帮助吗?
  • 我在添加适当的rowKey参数后再次尝试->仍然不起作用

标签: primefaces datatable multi-select


【解决方案1】:

我找到了所描述错误的来源: 带有 freezeColumns 的数据表的 Javascript 对象提供了一个函数来复制由 ajax 请求(如排序、过滤器等)接收的 's。 此函数不处理保存在 .

的数据 (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 尚未附加。 (老实说,我没有坚持到最后,如果我错了,请纠正我)

【讨论】:

    猜你喜欢
    • 2015-12-14
    • 2018-08-23
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多