John Cena
John Cena

Reputation: 11

Filter Datatable from Backing Bean jsf-primefaces

I have a primefaces datatable and i have a column with filter.i would like to apply filter on the column from the backing bean.

I followed this example and i am able to get the input given filter text box into my bean.

but when i use setFilter ,the values are being set in the HashMap but filter is not being applied on the datatable.

Example column

<p:column filterBy="#{var.value}" headerText="Example" footerText="contains" filterMatchMode="contains" />

Bean is session scoped and the following code is in a function which gets called on a button click.

Map<String,String> theFilterValues = new HashMap<String,String>();
    theFilterValues.put("filterColumn","someValue");
    myDataTable.setFilters(theFilterValues);

this sets the values ,but there is no change on datatable.

i tried this but it did not help.

All i need is to set a filter on the datatable column upon a button click. Thanks in advance

Upvotes: 1

Views: 5332

Answers (1)

Matruskan
Matruskan

Reputation: 353

The values in the inputs of the DataTable filter are sent in the FacesContext request parameter map, and obtained by the DataTableRenderer when it is rendering the DataTable (see the encodeFilter method for PF 3.5, PF 4.0, or PF 6.1)

So, if your button is in the same form of the DataTable, the values of the filter are sent in the request parameter map, and the renderer will show those values over whatever else you want.

You'll need the button to be in a separate form:

<h:form>
    <p:commandButton action="#{someBean.action()}" update="@([id$=dataTable])" />
</h:form>
<h:form>
    <p:dataTable id="dataTable" [...] >
        <p:column filterBy="#{var.col}" filterValue="#{someBean.filterValue}">
            <h:outputText value="#{var.col}">
        </p:column>
    </p:dataTable>
</h:form>

And then, you can change the filterValue in the bean:

@Named
@SessionScoped
public SomeBean implements Serializable {
    private String filterValue;
    [...]

    public void action() {
        filterValue = "new value";
    }

    [getters/setters]
}

You can use a Map for the filterValues if you are using many filters.


As an alternative, if you need to redirect the user to a new page, you can put the values in the URL, instead of using filterValue. Example:

https://example.com/app/pageOfTheTable.xhtml?form:dataTable:colum:filter=new%20value

The part form:dataTable:colum:filter is the ID of the filter input. You can get that by inspecting the element using your browser. The principle is the same: you are using the request parameter map.


It may be useful to update the value of the backing bean when the user types something. I've found a patch here.

It basically changes populateFilterParameterMap method, in FilterFeature class, so it sets the value of the filterValue. You can put the added lines at the end of the for loop.

for ( ... ){
    [...]

+   ValueExpression filterValueVE = column.getValueExpression("filterValue");
+   if (filterValueVE == null) {
+       ((UIComponent)column).getAttributes().put("filterValue", filterValue);
+   } else {
+       filterValueVE.setValue(context.getELContext(), filterValue);
+   }
}

Upvotes: 1

Related Questions