使用动态列过滤延迟的dataTable

时间:2014-06-12 09:38:49

标签: jsf primefaces datatable filtering lazy-loading

我有一个带动态列的dataTable:

<p:dataTable id="bookings" var="booking" value="#{tableBean.dataModel}" 
    widgetVar="bookingTable" filteredValue="#{tableBean.filteredFields}"
    paginator="true" rows="15"
    lazy="true" rowsPerPageTemplate="15,30,50" type="none" draggableColumns="true">

[...]

<p:columns value="#{tableBean.columns}" var="column" columnIndexVar="colIndex"
           sortBy="#{booking.properties[column.property]}"
           filterBy="#{booking.properties[column.property]}"
           filterMatchMode="in"
           styleClass="telegrotesk">
    <f:facet name="header">
        <h:outputText value="#{column.header}"/>
    </f:facet>
    <f:facet name="filter">
        <p:selectCheckboxMenu label="#{column.header}" onchange="PF('bookingTable').filter()">
            <f:selectItems value="#{column.possibilities}" />
        </p:selectCheckboxMenu>
    </f:facet>
    <h:outputText value="#{booking.properties[column.property]}"/>
</p:columns>

列类似于primefaces示例(http://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml)这个类:

static public class ColumnModel implements Serializable {

    private String header;
    private String property;
    private List<SelectItem> possibilities;

    public ColumnModel(Field property) {
        this.header = property.getName();
        this.property = property.getSqlName();
    }

    public String getHeader() {
        return header;
    }

    public String getProperty() {
        return property;
    }

    public List getPossibilities() {
        return possibilities;
    }

    public void setPossibilities(List<SelectItem> possibilities) {
        this.possibilities = possibilities;
    }
}

在我的示例中,仅测试一个动态列,该列显示创建预订的用户。它有效,在checkboxdropdown中显示所有用户。当我选择一个或多个用户时,功能加载

public List<Booking> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
    [...]
}

已执行,但过滤器始终为空!

ColumnModel中的列表可能性是SelectItems的集合。标签始终是用户名,User对象的值。对于用户类,我定义了一个使用javax.faces.convert.Converter

实现@FacesConverter(forClass = User.class)的Converter类

过滤器地图始终为空,我做错了什么?

修改

当我这样做时

<p:columns value="#{tableBean.columns}" var="column" columnIndexVar="colIndex"
           sortBy="#{booking.properties[column.property]}"
           filterBy="#{booking.properties[column.property]}"
           filterMatchMode="in"
           filterOptions="#{column.possibilities}"
           styleClass="telegrotesk">

并且没有方面它可以正常工作,但我只能选择一个用户。

我正在使用primefaces 5.0,jsf 2.2.1和glassfish v4

2 个答案:

答案 0 :(得分:1)

你没有做错任何事,这是一个Primefaces错误。

请为它加注星标,让我们尝试修复它。

新的PF5增强过滤不适用于动态列: https://code.google.com/p/primefaces/issues/detail?id=6912

解决方法:

第1步:在Primefaces源代码(https://code.google.com/p/primefaces/source/checkout)中打开FilterFeature.java。

populateFilterMetaData(FacesContext context, DataTable table)方法中,在第300行附近,替换:

filterId = dynamicColumn.getContainerClientId(context) + separator + "filter";
dynamicColumn.cleanStatelessModel();

用这个:

filterId = dynamicColumn.getContainerClientId(context) + separator + "filter";
filterFacet = null;
dynamicColumn.cleanStatelessModel();

所以基本上你只需添加filterFacet = null;

建立PF的提示:https://code.google.com/p/primefaces/wiki/BuildingFromSource

第2步:在项目中,确保过滤器构面中的输入组件的ID为过滤器

示例:

<f:facet name="filter">
    <p:selectOneButton id="filter" onchange="PF('recordTable').filter()" >
        <f:converter converterId="javax.faces.Boolean" />
        <f:selectItem itemLabel="All" itemValue="" />
        <f:selectItem itemLabel="True" itemValue="true" />
        <f:selectItem itemLabel="False" itemValue="false" />
    </p:selectOneButton>
</f:facet>

答案 1 :(得分:1)

是的,可以在primefaces 4.0 version

中的动态列中进行过滤选项
<p:columns value="#{pc_searchJobBean.columns}" var="column"
                                            id="searchJobColumns" columnIndexVar="colIndex"
                                            rendered="#{column.property eq 'minWorkExp' or column.property eq 'maxWorkExp' or column.property eq 'minSalary'
                                            or column.property eq 'maxSalary'}"
                                            filterBy="#{tbl[column.property]}" filterOptions="#{column.items}">

                                            <f:facet name="header">
                                                <h:outputText value="#{column.header}" escape="false">
                                                </h:outputText>
                                            </f:facet>

                                            <h:outputText value="#{tbl[column.property]}" escape="false"
                                                rendered="#{column.header!='Priority'}">
                                                <f:convertDateTime
                                                    pattern="#{userSettingBean.userSettingVO.dateFormat}" />
                                            </h:outputText>

                                        </p:columns>

Java代码......

public static class ColumnModel {

        private String header;
        private String property;
        private SelectItem[] items;

        public ColumnModel(String header, String property, SelectItem[] items) {
            super();
            this.header = header;
            this.property = property;
            this.setItems(items);
        }

        public ColumnModel(String header, String property) {
            this.header = header;
            this.property = property;
        }

        public String getHeader() {
            return header;
        }

        public void setHeader(String header) {
            this.header = header;
        }

        public String getProperty() {
            return property;
        }

        public void setProperty(String property) {
            this.property = property;
        }

        public SelectItem[] getItems() {
            return items;
        }

        public void setItems(SelectItem[] items) {
            this.items = items;
        }
    }

在列

中设置selectItems
if(model.getProperty().equals("country")){
                    model.setItems(countryOptions);
                }if(model.getProperty().equals("jobType")){
                    model.setItems(jobTypeOptions);
                }