简体   繁体   English

Primefaces selectCheckboxMenu过滤器不能正常工作,而selectOneMenu在数据表中

[英]Primefaces selectCheckboxMenu filter doesn't work while selectOneMenu well inside datatable

I have a Primefaces(5.0) datatable. 我有一个Primefaces(5.0)数据表。 I use two column filters: selectOneMenu(Filter1) and selectCheckboxMenu(Filter2). 我使用两个列过滤器:selectOneMenu(Filter1)和selectCheckboxMenu(Filter2)。

Both filter's data are being filled fine. 两个过滤器的数据都被正确填充。 selectOneMenu(Filter1) can filter the DataTable but the selectCheckboxMenu(Filter2) finds no any data after selecting a value. selectOneMenu(Filter1)可以过滤DataTable,但selectCheckboxMenu(Filter2)在选择值后没有找到任何数据。

JSF JSF

<p:dataTable value="#{employeeBean.employees}" var="employee" id="employeeDTable"
    emptyMessage="No data" filteredValue="#{employeeBean.filteredEmployees}"
    widgetVar="empWidgetVar" rowKey="#{employee.id}">

    <!-- THIS WORKS -->
    <p:column headerText="Filter1" filterBy="truck.id" filterMatchMode="exact">
        <f:facet name="filter">
            <p:selectOneMenu onchange="PF('empWidgetVar').filter()">
                <f:selectItems value="#{dropdowns.trucksWithAllOption}"/>
            </p:selectOneMenu>
        </f:facet>
        <h:outputText value="#{employee.truck.license}"/>
    </p:column>

    <!-- THIS DOESN'T WORK (Doesn't find any data) -->
    <p:column headerText="Filter2" filterBy="truck.id" filterMatchMode="in">
        <f:facet name="filter">
            <p:selectCheckboxMenu onchange="PF('empWidgetVar').filter()" label="Vrachtwagen">
                <f:selectItems value="#{dropdowns.trucksWithAllOption}"/>
            </p:selectCheckboxMenu>
        </f:facet>
        <h:outputText value="#{employee.truck.license}"/>
    </p:column>

</p:dataTable>

dropdowns.trucksWithAllOption dropdowns.trucksWithAllOption

在此输入图像描述

Rendered Filter1 渲染过滤器1

在此输入图像描述

Rendered Filter2 渲染Filter2

在此输入图像描述

Why selectCheckboxMenu(Filter2) can't find any data while selectOneMenu(Filter1) finds well with the same data? 为什么selectCheckboxMenu(Filter2)找不到任何数据而selectOneMenu(Filter1)找不到相同的数据?

I know this might be an old question, but I've been struggling with selectCheckboxMenu Filter for days now, and I finally found a solution. 我知道这可能是个老问题,但我现在一直在努力使用selectCheckboxMenu过滤器,我终于找到了解决方案。 First of all, there are several things you should do in your code to get this filter to work: 首先,您应该在代码中执行以下操作以使此过滤器起作用:

  • filterBy set to the exact value that you are displaying in outputText filterBy设置为您在outputText中显示的确切值
  • String[] value to store your selected filter values in your bean String []值,用于在bean中存储选定的过滤器值
  • catch change and selectAll checkbox events with ajax and trigger the PrimeFaces filter function 捕获更改并使用ajax选择所有复选框事件并触发PrimeFaces过滤器功能
  • bind a listener in your bean to handle the filter events when triggered by selectCheckboxMenu 绑定bean中的侦听器以在selectCheckboxMenu触发时处理过滤器事件
  • to avoid problems with javascript versions, just set both your table ID and widgetVar to the same value (in our example "TABLEID") 为了避免javascript版本的问题,只需将表ID和widgetVar设置为相同的值(在我们的示例“TABLEID”中)
  • Set ID in your UI component and figure out the index of this column in the datatable. 在UI组件中设置ID,并在数据表中找出此列的索引。 Best is to set these two as constants in your controller or presenter 最好是将这两个设置为控制器或演示者中的常量

     <p:column id="columnLicenses" headerText="Filter2" filterBy="employee.truck.license" filterMatchMode="in"> <f:facet name="filter"> <p:selectCheckboxMenu value="#{employeeBean.selectedTrucks}" label="Vrachtwagen"> <f:selectItems value="#{dropdowns.trucksWithAllOption}"/> <p:ajax event="change" process="@this" update=":FORMID" listener="#{employeeBean.onFilter()}" oncomplete="PF('TABLEID').filter()" /> <p:ajax event="toggleSelect" process="@this" update=":FORMID" listener="#{employeeBean.onFilter()}" oncomplete="PF('TABLEID').filter()" /> </p:selectCheckboxMenu> </f:facet> <h:outputText value="#{employee.truck.license}"/> 

In your bean, you need to implement the listener. 在bean中,您需要实现侦听器。 Also you need to implement the method that is going to load your actual FilterMeta object into the FilterMetadata object, that belongs to the datatable object. 您还需要实现将实际FilterMeta对象加载到属于datatable对象的FilterMetadata对象的方法。 Since PrimeFaces does not pass the good value for String array selection value filter, we are basically going to wire this array in our bean, and then convert it to the FilterMeta object that PrimeFaces did not deliver. 由于PrimeFaces没有为String数组选择值过滤器传递好的值,我们基本上将在我们的bean中连接这个数组,然后将它转换为PrimeFaces没有提供的FilterMeta对象。 So add following code to your bean: 所以将以下代码添加到您的bean:

private static final String TABLE_ID = "TABLEID";
private static final String COLUMN_ID_LICENSES = "columnLicenses";
private static final int COLUMN_INDEX_LICENSES = 2; // for example, it is third column in the table
private String [] selectedTrucks; // Also generate getter and setter for this

public void onFilter() {
        DataTable table = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(TABLE_ID);
        updateCollectionFilterFor(table, COLUMN_ID_LICENSES, selectedTrucks,
                COLUMN_INDEX_LICENSES);
    }

@SuppressWarnings("unchecked")
private void updateCollectionFilterFor(final DataTable table, final String columnId, final String[] filterValue,
        int columnIndex) {
    for (UIColumn column : table.getColumns()) {
        if (column.getClientId().contains(columnId)) {
            ValueExpression columnFilterByVE = column.getValueExpression("filterBy");
            if (null != columnFilterByVE) {
                FilterMeta fm = new FilterMeta(column, columnFilterByVE, filterValue);
                table.getFilterMetadata().remove(columnIndex);
                table.getFilterMetadata().add(columnIndex, fm);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM