I have a Primefaces(5.0) datatable. I use two column filters: selectOneMenu(Filter1) and 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.
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
Rendered Filter1
Rendered Filter2
Why selectCheckboxMenu(Filter2) can't find any data while selectOneMenu(Filter1) finds well with the same data?
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. First of all, there are several things you should do in your code to get this filter to work:
Set ID in your UI component and figure out the index of this column in the datatable. 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. 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. 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. So add following code to your 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);
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With