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));
}
}

