【问题标题】:Primefaces selectCheckboxMenu filter doesn't work while selectOneMenu well inside datatablePrimefaces selectCheckboxMenu 过滤器在 selectOneMenu 位于数据表内时不​​起作用
【发布时间】:2014-07-07 20:32:02
【问题描述】:

我有一个 Primefaces(5.0) 数据表。我使用两个列过滤器:selectOneMenu(Filter1) 和 selectCheckboxMenu(Filter2)。

两个过滤器的数据都被很好地填充了。 selectOneMenu(Filter1) 可以过滤DataTable,但是selectCheckboxMenu(Filter2) 选择一个值后没有找到任何数据。

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

渲染滤镜1

渲染过滤器2

为什么 selectCheckboxMenu(Filter2) 找不到任何数据,而 selectOneMenu(Filter1) 可以很好地找到相同的数据?

【问题讨论】:

  • 我也遇到同样的问题。selectCheckBox 值预计为数组。我认为它是因为调用了 selectCheckBox 值属性的toString()。prime 团队应该尽快修复@cagatay-civici

标签: jsf primefaces datatable


【解决方案1】:

我知道这可能是一个老问题,但我一直在努力使用 selectCheckboxMenu 过滤器好几天了,我终于找到了解决方案。 首先,你应该在你的代码中做几件事来让这个过滤器工作:

  • filterBy 设置为您在 outputText 中显示的确切值
  • String[] 值将您选择的过滤器值存储在您的 bean 中
  • 使用 ajax 捕获更改和 selectAll 复选框事件并触发 PrimeFaces 过滤功能
  • 在您的 bean 中绑定一个侦听器以在 selectCheckboxMenu 触发时处理过滤器事件
  • 为避免 javascript 版本出现问题,只需将表 ID 和 widgetVar 设置为相同的值(在我们的示例中为“TABLEID”)
  • 在您的 UI 组件中设置 ID 并找出该列在数据表中的索引。最好将这两个设置为您的控制器或演示器中的常量

    <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}"/>
    

在您的 bean 中,您需要实现侦听器。此外,您还需要实现将实际 FilterMeta 对象加载到属于数据表对象的 FilterMetadata 对象的方法。由于 PrimeFaces 没有通过 String 数组选择值过滤器的好值,我们基本上是将这个数组连接到我们的 bean 中,然后将其转换为 PrimeFaces 未提供的 FilterMeta 对象。因此,将以下代码添加到您的 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);
            }
        }
    }
}

【讨论】:

  • 我在答案编辑器中添加 xhtml 代码时遇到问题 XD
  • 代码看起来不错,虽然我很难理解问题和解决方案。但这可能是因为我总是使用lazyDataModel,从不需要奇怪的“解决方案”或修复
  • 该列的结束标记仍未显示。无论如何,我必须使用非惰性模型,以及自定义的 PrimeFaces 库,而且表必须显式绑定到控制器中的对象。那个更糟...但是您使用lazyDataModel从未遇到过这些问题?
  • 结束标签前面只有一个空格。然后它被解释为没有意义的“html”。不,如果操作正确,lazyDataModel 没有问题
猜你喜欢
  • 1970-01-01
  • 2017-01-21
  • 2016-06-29
  • 2014-08-09
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 1970-01-01
相关资源
最近更新 更多