Friday, May 20, 2011

Making the 'Reset' button in af:query component clear the existing results from the result table.

Problem :  Clicking the 'Reset' button in an af:query does not clear the previous result rows from the result table.

Solution : Implement a QueryOperationListener and call executeEmptyRowSet() on the viewObject that back up the result table and the query.
This seems to be an often requested feature, and I guess it originates from the user's expectation from what a button called "Reset" should do when clicked. In a lot of cases the af:query component is accompanied by a result table and the user expects the data from a previous query to be cleared from the table when the 'Reset' button on the query component is clicked. This however is not the default behaviour, and clicking the 'Reset' button only clears the query criteria entered. So lets get on with it...


First define a QueryOperationListener for the af:query component. You will implement this as a backing bean method.



The backing bean code can be like this :

public void processQueryOperation(QueryOperationEvent queryOperationEvent)
  { 
    //This is to make sure that we don't just trap the call. 
    invokeMethodExpression(
             "#{bindings.//Your_search_binding//.processQueryOperation}",
              Object.class, 
              QueryOperationEvent.class,
              queryOperationEvent);

    if (Operation.RESET.name().equals(queryOperationEvent.getOperation().name()))
    {

      DCBindingContainer bindingContainer = (DCBindingContainer)
                            JSFUtils.resolveExpression("#{bindings}");
      DCIteratorBinding iter =
                         bindingContainer.findIteratorBinding(
                                            //name_of_the_VO_iterator//);
      // we have the iterator 
      // now get the VO and execute the empty RowSet to clear it
      iter.getViewObject().executeEmptyRowSet();

      // Now that the rows are cleared from the VO, referesh the UI Table.
      AdfFacesContext.getCurrentInstance()
                      .addPartialTarget(JSFUtils.findComponent(
                                                  "//ID of the af:table// "));

    }

Details on invokeMethodExpression can be found here, and replace the name of your searchBinding (you can find it from the page def's executables section) in the call to invokeMethodExpression.
JSFUtils is part of the ADF demo app from Oracle. Its a pretty good idea to have this in your project as a helper class. You should replace the name of your VO's ierator (you can find this out from the pageDef's executables section) and the ID of the af:table.