Filtrar una tabla de datos perezosa con columnas dinámicas

I have a dataTable with dynamic Columns:

<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>

column is similar like in the primefaces example (http://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml) this class:

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;
    }
}

In my example there is for testing only one dynamic column, that shows the User that created a booking. It works, that in the checkboxdropdown are shown all users. When I select one or more users, the function load

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

is executed, but filters is always empty!

The list possibilities in the ColumnModel es una colección de SelectItems. The label is always the username, the value the User object. For the user class I defined a Converter class implementing javax.faces.convert.Converter con el @FacesConverter(forClass = User.class)

What am I doing wrong that the filter map is always empty?

EDITAR

When I do it like this

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

and with no facet it works correctly but I can only select one User.

I'm using primefaces 5.0, jsf 2.2.1 and glassfish v4

preguntado el 12 de junio de 14 a las 10:06

2 Respuestas

You did nothing wrong, this is a Primefaces bug.

Please star it, let's try and get it fixed.

New PF5 enhanced filtering does not work with Dynamic Columns: https://code.google.com/p/primefaces/issues/detail?id=6912

Solución del problema:

Paso 1: In the Primefaces source (https://code.google.com/p/primefaces/source/checkout) open FilterFeature.java.

En el caso populateFilterMetaData(FacesContext context, DataTable table) method, around line 300, replace:

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

con este:

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

So basically you just add filterFacet = null;

Tips for building PF: https://code.google.com/p/primefaces/wiki/BuildingFromSource

Paso 2: In your project, ensure that your input component in the filter facet has an id of filtrar

Ejemplo:

<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>

Respondido el 13 de enero de 15 a las 15:01

yes it's possible to do filter options in dynamic columns in 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 code...

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;
        }
    }

Set selectItems in columns

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

Respondido 17 ago 16, 13:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.