The idea is to have a couple of buttons in the table header to make the filter visible, and to disable and clear the filter itself:
After the filter is enabled, the text box appears, and as soon as the user starts typing, the autosuggestion kicks in:
This is what we need on the page/fragment:
A button to activate the filter (i.e. make the filter visible):
<af:commandButton text="Filter" id="cbFilter" rendered="true" partialSubmit="true" disabled="#{pageFlowScope.filter}" styleClass="btn"> <af:setActionListener from="true" to="#{pageFlowScope.filter}"/> </af:commandButton>
A button to deactivate and clear the filter:
<af:commandButton text="#{vehicleBundle.SELECTIVE_TABLE_FILTER_DISABLE}" id="cbDFilter" rendered="true" partialSubmit="true" actionListener="#{viewScope.vehicleBean.resetTableFilter}" disabled="#{!pageFlowScope.filter}" styleClass="btn"> <af:setActionListener from="false" to="#{pageFlowScope.filter}"/> </af:commandButton>
This is the table containing the filter: in the column we want to filter, we have an af:inputText component with autosuggest behavior operation, and two buttons to perform the filtering and clear the filter.
<af:table value="#{bindings.vehicleList1.collectionModel}" var="row" rows="#{bindings.vehicleList1.rangeSize}" fetchSize="5" varStatus="vs" partialTriggers=":cbDFilter :cbFilter" filterModel="#{bindings.vehicleListQuery.queryDescriptor}" queryListener="#{bindings.vehicleListQuery.processQuery}" filterVisible="#{pageFlowScope.filter}" id="listVehicles" [ . . . ]> [ . . .] <af:column filterable="true" filterFeatures="caseInsensitive" headerText="#{vehicleBundle.VEHICLE_DESC}" id="cVD"> <f:facet name="filter"> <af:panelGroupLayout id="pgAS" layout="vertical"> <af:outputText value="#{vehicleBundle.FILTER_VEHICLES}" id="oFMsg"/> <af:panelGroupLayout id="pgFL" layout="horizontal"> <af:inputText id="itFL" value="#{vs.filterCriteria.vehicleDescription}" autoSubmit="true" usage="search"> <af:autoSuggestBehavior suggestItems="#{viewScope.vehicleBean.suggestedVehicles}"/> </af:inputText> <af:commandButton partialSubmit="true" id="cbexecute" text="Filter"/> <af:commandButton partialSubmit="true" id="cbclear" text="Clear" actionListener="#{viewScope.vehicleBean.resetTableFilter}"/> </af:panelGroupLayout> </af:panelGroupLayout> </f:facet> </af:column>
In this case, we need the item type returned from the iterator to expose an attribute called 'vehicleDescription'.
Since the table is supposed to show a collection of Vehicle objects, the Vehicle class needs to have a 'vehicleDescription' property (or a getter method called 'getVehicleDescription').
So the page definition for this page/fragment will contain something like this:
<tree IterBinding="vehiclesIterator" id="vehicleList1"> <nodeDefinition DefName="com.test.Vehicle" Name="vehicleList10"> <AttrNames> <Item Value="id"/> <Item Value="vciIdentifier"/> [. . .] <Item Value="vehicleDescription"/> </AttrNames> </nodeDefinition> </tree> [. . .] <searchRegion Binds="vehiclesIterator" Criteria="" Customizer="oracle.jbo.uicli.binding.JUSearchBindingCustomizer" id="vehicleListQuery"/>Here are the methods needed:
public List suggestedVehicles(FacesContext facesContext, AutoSuggestUIHints autoSuggestUIHints) { // Add event code here... List<SelectItem> suggestions = autoSuggestIterator("vehiclesIterator", "vehicleDescription", autoSuggestUIHints.getSubmittedValue()); return suggestions; } public void resetTableFilter(ActionEvent actionEvent) { // Add event code here... resetTableFilter("listVehicles"); } public List<SelectItem> autoSuggestIterator(String iterator, String listValue, String input){ // Add event code here... DCIteratorBinding binding = ADFUtils.findIterator(iterator); int rangeSize = binding.getRangeSize(); binding.setRangeSize(1000); List suggestionList = ADFUtils.attributeListForIterator(iterator, listValue); List<SelectItem> suggestions = new ArrayList<SelectItem>(); for (int i = 0; i < suggestionList.size(); i++) { if (suggestionList.get(i).toString().toUpperCase().contains(input.toUpperCase())) { suggestions.add(new SelectItem(suggestionList.get(i))); } } binding.setRangeSize(rangeSize); return suggestions; } public List attributeListForIterator(DCIteratorBinding iter, String valueAttrName) { List attributeList = new ArrayList(); for (Row r : iter.getAllRowsInRange()) { attributeList.add(r.getAttribute(valueAttrName)); } return attributeList; } public void resetTableFilter(String tableId) { UIComponent uiComponent = JSFUtils.findComponentInRoot(tableId); RichTable table = (RichTable)uiComponent; FilterableQueryDescriptor queryDescriptor = (FilterableQueryDescriptor)table.getFilterModel(); if (queryDescriptor != null && queryDescriptor.getFilterCriteria() != null) { queryDescriptor.getFilterCriteria().clear(); table.queueEvent(new QueryEvent(table, queryDescriptor)); } }