【问题标题】:How to filter a p:dataTable with selectionMode with p:selectCheckboxMenu?如何使用 p:selectCheckboxMenu 过滤带有 selectionMode 的 p:dataTable?
【发布时间】:2017-02-11 05:30:53
【问题描述】:

我正在尝试在一个列标题中过滤带有 Primefaces 组件 p:selectCheckboxMenup:dataTable。然而,这并没有按预期工作。数据表上的其他过滤器工作得很好,例如输入字段。 有问题的列是Room type,它有p:selectCheckboxMenu

过滤工作一次,之后选中或取消选中 selectCheckbox 菜单上的复选框不会添加或删除表格上的任何过滤。

关于这个问题有一个有趣的地方:

如果我从datatable 中删除selectionMode="single" 属性,那么即使在第一个复选框切换之后,排序也会起作用。如,我可以切换和取消切换一个框,p:dataTable 会被相应地过滤。但是,我在这里需要选择模式,因为我应该能够选择一行并通过单击它导航到另一个视图。当datatable 上没有selectionMode 属性时,这不起作用。

这是我的数据表:

<div class="background">

        <div class="freeRoomsContent">

            <br/>
            <p:outputLabel value="free rooms" styleClass="headerfont"/>
            <br/>
    <h:form id="freeRoomsForm">
        <p:dataTable id="freeRoomsTable" var="room" paginatorPosition="bottom" paginatorAlwaysVisible="false"
                     value="#{freeRoomsController.freeRoomsList}" selectionMode="single" selection="#{freeRoomsController.room}"
                     rowKey="#{room.roomId}" widgetVar="freeRoomsTable"
                     paginator="true" rows="20" pageLinks="5" scrollable="false"
                     paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                     rowsPerPageTemplate="20,50,100" skipChildren="true" emptyMessage="No free rooms available.">
            <p:ajax event="rowSelect" listener="#{freeRoomsController.onRowSelect}" />
            <p:column headerText="Room Id" sortBy="#{room.roomId}" filterMatchMode="contains" filterBy="#{room.roomId}">
                <h:outputText value="#{room.roomId}"/>
              </p:column>

            <p:column headerText="Room number" sortBy="#{room.roomNumber}" filterMatchMode="contains" filterBy="#{room.roomNumber}">
                <h:outputText value="#{room.roomNumber}" />
            </p:column>
<!-- other similar columns -->

            <p:column headerText="Room type" filterMatchMode="exact" filterBy="#{room.roomType}">
                <f:facet name="filter">
                    <p:selectCheckboxMenu  onchange="PF('freeRoomsTable').filter()"
                                     label="Room type">
                        <f:selectItems value="#{staticData.roomTypes}" var="rt" itemLabel="#{msg[rt.name]}" itemValue="#{rt.name}"
                                       />
                    <p:ajax event="change" process="@this" update="freeRoomsForm" />
                    <p:ajax event="toggleSelect" process="@this" update="freeRoomsForm" />
                    </p:selectCheckboxMenu>
                </f:facet>
                <h:outputText value="#{msg[room.roomtype.name]}">
                    <f:convertDateTime pattern="dd.MM.yyyy" />
                </h:outputText>
            </p:column>

<!-- normal input field columns that work -->

        </p:dataTable>
    </h:form>
</div>
</div>

【问题讨论】:

  • 您是否尝试过 删除 p:ajax 嵌套在 p:selectCheckboxmenu 中?我认为 filter() 函数本身会触发 ajax 请求。另外,尝试添加 p:ajax event=filter 嵌套在数据表中(例如,在 p:ajax 下方用于 rowSelect)

标签: jsf primefaces datatable filtering


【解决方案1】:

这对我有用:

  • p:dataTable 中使用 valuefilteredValue

  • 仅使用onchange=PF('freeRoomsTable').filter(),在p:selectCheckboxMenu 中没有子p:ajax 元素

  • p:selectCheckboxMenu 设置value 属性,例如value="#{someBean.selectedItems}"

  • 在你的bean中,使用private String[] selectedItems,带有getter和setter

  • 在您的 bean 实现 filterFunction 中,方法需要具有签名 boolean (Object, Object, Locale),尽管对于此示例仅使用第一个参数(对象值):
    public boolean filterFunction(Object value, Object filter, Locale locale) {
    
        // instanceof checking probably not needed
        if (value == null || !(value instanceof String)) {
            return true;  
        }
    
        String valueInRow = (String)value;
    
        // if nothing is selected, show row in table i.e. return true, 
        // you can play with this ofcourse
        if (selectedItems == null || selectedItems.length == 0) {
            return true;
        }
    
        // if item in row matches any of the items that were selected in header,    
        // show in table i.e. return true
        for (int i = 0; i < selectedItems.length; i++) {
            if (selectedItems[i].equals(valueInRow)) {
                return true;
            }
        }
    
        // if you don't want to show row in table, return false
        return false;
    
    }
    

  • p:column 中,调用filterfunction=#{someBean.filterFunction} - 没有参数,没有括号,不需要使用任何filterMatchMode,只留下filterBy
  • 【讨论】:

    • 谢谢!明天试试。我会检查你的答案是否正确。
    • 我完成了这里提到的所有步骤。 filterFunction 在我切换框时被调用,并且该方法作为值参数获取所有显示在 freeRoomsTable 上的房间类型。但是, selectedItems String[] 数组始终为空。打开视图后,不会访问它的 getter 和 setter。支持 bean 是 @ViewScoped。我按照您的指示使用字符串数组:
    • 如果没有 Java 代码和页面的其余部分,我无法进一步告诉您...尝试更改为 SessionScoped 以查看它是否有效。而且我发现很难相信 getter 和 setter 根本没有被调用。另外,我注意到你得到了 skipChildren=true,请尝试删除它。
    • 你是个天才。不知道为什么我首先添加了该 skipChildren 属性。可能在某个时候进行了一些绝望的解决方法尝试。无论如何,现在它可以工作了!除了...“全选”选项:) 目前这不是什么大问题。有任何想法吗?无论如何,我会检查你的答案是否正确,因为你会在上面添加“删除 skipChildren”。
    • 是的,我注意到全选也有问题...试试这个:stackoverflow.com/a/24824162/1072089,我还没试过。在最坏的情况下,您可能有 2 个连续的 ajax 请求,第一个用于切换全选并且什么都不做,然后第二个用于过滤。类似于
    猜你喜欢
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2019-03-01
    相关资源
    最近更新 更多