Friday, May 3, 2013

Programatic handle to ADF Query Component - see Query Input values


You can create ADF Query search forms that will allow users to search based on some input fields. The results of the query can be displayed as ADF Table , form or any other ADF UI Component . In general search forms are based on af:query and af:quickquery components.


ADF Search forms are based on view criteria defined at ADF VO level or implicit view criteria defined by the framework . Once you define the View criteria ,drag and drop it from the data control palette on the the page as ADF Query pane with table . ADF will take care of the rest of the things. Everything will be configured on its own ranging from search button binding  to the particular model and to the table which is being refreshed whenever results are being fetched .

Suppose we may want to modify the query values / see the current query values / validate the user input . we will see how to get handle to the ADF Query component to do this .


you will see the ADF:Query pane code in the page like this :

<af:query id="qryId1" headerText="Search" disclosed="true"
value="#{bindings.VOCriteriaQuery.queryDescriptor}" 
model="#{bindings.VOCriteriaQuery.queryModel}" queryListener="#{bindings.VOCriteriaQuery.processQuery}" 
queryOperationListener="#{bindings.VOCriteriaQuery.processQueryOperation}" resultComponentId="::resId1"/> 

queryListener having an expression that deals with invoking of corresponding binding dynamically. In order to get handle to this component we will write our custom method and bind it to the queryListener.

After modifying it looks like queryListener="#{backingBeanScope.managedBean1.onSearch}"

 The Below custom method will tell you everything in clear

  public void onSearch(QueryEvent queryEvent) {
       
        String EmployeeId = null;
        // Query Event is delivered when a query action is triggered
        QueryDescriptor qd = queryEvent.getDescriptor();
       
        // This line will represent group of criterion objects
        ConjunctionCriterion conCrit = qd.getConjunctionCriterion();
       
        //access the list of all search fields
        List<Criterion> criterionList = conCrit.getCriterionList();

        for (Criterion criterion : criterionList) {
            AttributeDescriptor attrDescriptor =  ((AttributeCriterion)criterion).getAttribute();

            if (attrDescriptor.getName().equalsIgnoreCase("EmployeeId")) { // EmployeeId is one of the query items in the search pane
             EmployeeId  =  (String)((AttributeCriterion)criterion).getValues().get(0);
             
            //This is how we will access the query field
             System.out.println("EmployeeId :" + EmployeeId );

            }
        }


        DCBindingContainer bc =
            (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        ViewCriteria vc = getViewCriteria(bc, qd);

    System.out.println("View Object"+ vc.getViewObject);

    //Execute the query Listener using EL. This will execute the query component .If u see the exp , this was initially applied to QueryListener.. Later we assigned QueryListener to our custom method.
     
   invokeMethodExpression("#{bindings.VOCriteriaQuery.processQuery}", queryEvent); 
       
    }
    
      //helper method to execute the QueryListener EL

       private void invokeMethodExpression(String expr, QueryEvent queryEvent) {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ELContext elContext = fctx.getELContext();
        ExpressionFactory eFactory =
            fctx.getApplication().getExpressionFactory();
        MethodExpression mexpr =
            eFactory.createMethodExpression(elContext, expr, Object.class,
                                            new Class[] { QueryEvent.class });
        mexpr.invoke(elContext, new Object[] { queryEvent });
    }
 


    private ViewCriteria getViewCriteria(DCBindingContainer bc,
                                         QueryDescriptor qd) {

        Object execBinding =  bc.findExecutableBinding("VOCriteriaQuery"); // This will be seen in the page executable section as we have dropped for af:query
        ViewCriteria vc =
            JUSearchBindingCustomizer.getViewCriteria((DCBindingContainer)execBinding,
                                                      qd.getName());
        return vc;

    }


2 comments:

  1. nice article, thanks alot to bring it.
    Can you tell me, how the way get list value from criteria item with support multiple selection?

    ReplyDelete
  2. Is it possible to edit the result from af:query using this method. Like getting handle on the result data to the UI.

    ReplyDelete