Filtering is also enabled on our table. The filter facet is where I am able to specify the filters I’d like to be able to apply to the table. Due to a JavaScript issue I have yet to track down (which may or may not be related to my nascent Facelets support), my implementation here is a bit different from the Woodstock examples. Here is the source for filterMenuChanged:
function filterMenuChanged(cb) {
if (cb.value == "_customFilter") {
var ret = document.getElementById(tableId).filterMenuChanged();
return ret;
} else if (cb.value == "FILTER_SHOW_ALL") {
window.location.href=window.location.href;
}
}
It basically checks for the special option element Woodstock adds to determine if a custom filter is being requested (which causes the filter panel to be displayed), or if the "show all" option was selected, which will clear the filter. Note that this JavaScript is not optimal and has changed a fair amount as my understanding of the component has grown, and will likely do so again. Ideally, I’ll solve the JavaScript error that prompted this so that this can go away.
The next item of interest is the filterPanel facet, which is display when the user selects the "Custom Filter" option. The markup here pretty simple, in that all I have are a number of custom filters (though I’ve shown only one) that are nothing more than a label, an appropriate UIInput component, and a button. The only thing really noteworthy is the JavaScript used to apply the filter. Via EL, we’re taking the value entered or selected by the user, and setting that on a property on the Filter class (which I added to the Sun-provided class to make things more reusable). Since every field on the form will get set on the managed bean referenced via its EL, we can’t have them all pointing at the same property. To solve this problem, I use some simple JavaScript to copy the value in which I’m interested to a hidden field, which is the only one assigned to the desired property. I also use a <f:setPropertyActionListener> to set which field should be filtered:
<w:button action="#\{ewl.group.filter.applyCustomFilter}" mini="true"
text="OK" onClick="applyCustomFilter('timePending');">
<f:setPropertyActionListener value="timePendingClass"
target="#\{ewl.group.filter.customFilterField}"/>
</w:button>
The source for applyCustomFilter is
function applyCustomFilter(source) {
document.getElementById('pendingUnits:table:filterPanel:customFilter').value =
document.getElementById('pendingUnits:table:filterPanel:' + source).value;
}
When the form submits, the appropriate properties on the Filter object are set, and the filters are applied to the DataProvider:
public void applyCustomFilter() {
basicFilter = Table.CUSTOM_FILTER_APPLIED; // Set filter menu option.
filterText = "Custom - " + customFilter;
// Filter rows that do not match custom filter.
CompareFilterCriteria criteria = new CompareFilterCriteria(
group.getProvider().getFieldKey(customFilterField), customFilter);
// Note: TableRowGroup ensures pagination is reset per UI guidelines.
group.getTableRowGroup().setFilterCriteria(new FilterCriteria[] \{criteria});
}