Reputation: 3548
I'm trying to filter a p:dataTable
with Primefaces component p:selectCheckboxMenu
in one column header. This however, does not work as intended. The other filters on the datatable work just fine, such as input fields.
The column in question is the Room type
, that has the p:selectCheckboxMenu
.
The filtering works once, after that checking or unchecking boxes on the selectCheckbox menu doesn't add or remove any filtering on the table.
Here's an interesting bit on the problem:
If I remove the selectionMode="single"
attribute from the datatable
, then the sorting works even after the first checkBox toggle. As in, I can toggle and untoggle a box and the p:dataTable
gets filtered accordingly. But, I need the selection mode here, since I'm supposed to be able to select a row and navigate to another view by clicking it. That doesn't work when there's no selectionMode
attribute on the datatable
.
Here's my datatable:
<div class="background">
<div class="freeRoomsContent">
<br/>
<p:outputLabel value="free rooms" styleClass="headerfont"/>
<br/>
<h:form id="freeRoomsForm">
<p:dataTable id="freeRoomsTable" var="room" paginatorPosition="bottom" paginatorAlwaysVisible="false"
value="#{freeRoomsController.freeRoomsList}" selectionMode="single" selection="#{freeRoomsController.room}"
rowKey="#{room.roomId}" widgetVar="freeRoomsTable"
paginator="true" rows="20" pageLinks="5" scrollable="false"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="20,50,100" skipChildren="true" emptyMessage="No free rooms available.">
<p:ajax event="rowSelect" listener="#{freeRoomsController.onRowSelect}" />
<p:column headerText="Room Id" sortBy="#{room.roomId}" filterMatchMode="contains" filterBy="#{room.roomId}">
<h:outputText value="#{room.roomId}"/>
</p:column>
<p:column headerText="Room number" sortBy="#{room.roomNumber}" filterMatchMode="contains" filterBy="#{room.roomNumber}">
<h:outputText value="#{room.roomNumber}" />
</p:column>
<!-- other similar columns -->
<p:column headerText="Room type" filterMatchMode="exact" filterBy="#{room.roomType}">
<f:facet name="filter">
<p:selectCheckboxMenu onchange="PF('freeRoomsTable').filter()"
label="Room type">
<f:selectItems value="#{staticData.roomTypes}" var="rt" itemLabel="#{msg[rt.name]}" itemValue="#{rt.name}"
/>
<p:ajax event="change" process="@this" update="freeRoomsForm" />
<p:ajax event="toggleSelect" process="@this" update="freeRoomsForm" />
</p:selectCheckboxMenu>
</f:facet>
<h:outputText value="#{msg[room.roomtype.name]}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
</p:column>
<!-- normal input field columns that work -->
</p:dataTable>
</h:form>
</div>
</div>
Upvotes: 1
Views: 5896
Reputation: 623
This worked for me:
p:dataTable
onchange=PF('freeRoomsTable').filter()
, without child p:ajax
elements in p:selectCheckboxMenu
value
attribute for p:selectCheckboxMenu
, e.g. value="#{someBean.selectedItems}"
private String[] selectedItems
, with getter and setter
public boolean filterFunction(Object value, Object filter, Locale locale) {
// instanceof checking probably not needed
if (value == null || !(value instanceof String)) {
return true;
}
String valueInRow = (String)value;
// if nothing is selected, show row in table i.e. return true,
// you can play with this ofcourse
if (selectedItems == null || selectedItems.length == 0) {
return true;
}
// if item in row matches any of the items that were selected in header,
// show in table i.e. return true
for (int i = 0; i < selectedItems.length; i++) {
if (selectedItems[i].equals(valueInRow)) {
return true;
}
}
// if you don't want to show row in table, return false
return false;
}
p:column
, call filterfunction=#{someBean.filterFunction}
- no arguments, no parenthesis, no need to use any filterMatchMode, leave only filterBy
Upvotes: 3