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.

2 comments:

  1. After coding as above, Reset also resets the Results.

    Following scenario is not working after this.

    Navigate to Advanced Search by clicking Advanced button in Query Panel.

    Click Add Fields button and add a filed to Query Panel.

    Click on Basic or Reset, it is throwing NULL POINTER EXCEPTION.

    After removing the code for Reset mentioned in this blog, Advanced Search, Basic, Reset are working as expected.

    ReplyDelete
    Replies
    1. Vinod,
      The blog post is designed show how to clear the results also when hitting the reset button. The default behavior is to reset the search criteria and leave the previous results as is. If that is what you need, you need not so anything: thats how the af:query behaves out-of-the-box.

      If you do need to clear the results, then read on :
      About the Nullpointer, have you checked where the null pointer is coming from ? The example code above does not do any null checks. But you should be able to see what is null and implement a null check based on it.
      Hope that clears it up...

      Delete