Tuesday 21 February 2017

How to remove RESET button in Query component af:query in ADF

Use case - Our requirement was to remove reset and save buttons and show just Search button.

In af:query by default Basic mode gets enabled, which can be updated from ViewCriteria UIHints to basic.

Basic mode for Employee VO will look something like below:




There is no direct way to just hide buttons but we can change displayMode="simple" and UI will look like something below:

 

Now to implement Search button we can add a command button additional with Execute operation.

 <af:panelGroupLayout layout="vertical" id="pgl1">
    <af:panelHeader text="EmployeesEO" id="ph1">
      <af:query id="qryId1" headerText="Search" disclosed="true"
                queryListener="#{bindings.EmployeesViewCriteriaQuery.processQuery}"
                queryOperationListener="#{bindings.EmployeesViewCriteriaQuery.processQueryOperation}"
                value="#{bindings.EmployeesViewCriteriaQuery.queryDescriptor}"
                model="#{bindings.EmployeesViewCriteriaQuery.queryModel}"
                displayMode="simple" modeChangeVisible="false" saveQueryMode="hidden"
                resultComponentId="::resId1">
        </af:query>    
    <af:commandButton actionListener="#{test.executeMyQuery}"
                        text="Search"
                        id="cb1"/>
    
    </af:panelHeader>


 

*Comments and feedback are most welcomed, Thanks.

How to override default queryListener and queryOperationListener in ADF af:query

There will be many use case in real time application when we need to override af:query listener methods to write our custom logic.

Let's assume below use case:

We need to suppress required field validation  when clicked of saved search in af:query UI.








When we click on operation such as Select and Create, QueryEvent will be fired after QueryOperationEvent.

The required field validation will be fired after queryListener.

As a solution, we can override the QueryEvent, QueryOperationEvent method and skip executing QueryEvent whenever the operation such as CREATE and SELECT will be fired.

In JSFF we will override  queryListener and queryOperationListener

<af:panelHeader text="EmployeesEO" id="ph1">
      <af:query id="qryId1" headerText="Search" disclosed="true"
                value="#{bindings.EmployeesViewCriteriaQuery.queryDescriptor}"
                model="#{bindings.EmployeesViewCriteriaQuery.queryModel}"
                queryListener="#{queryHandler.queryListener}"
                queryOperationListener="#{queryHandler.queryOperationListener}"
                resultComponentId="::resId1">
        </af:query>    
    </af:panelHeader>

Note: queryHandler bean is put in request scope.


import java.util.Arrays;
import java.util.List;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.event.QueryEvent;
import oracle.adf.view.rich.event.QueryOperationEvent;


public class QueryHandler{
   
        private boolean isNotSaveOperation = true;
        private final List<String> operationList =
            Arrays.asList("CREATE", "SELECT");

        //Overriden queryOperationListener method
        public void queryOperationListener(QueryOperationEvent queryOperationEvent) {
            String operationName = queryOperationEvent.getOperation().name();
            System.out.println("Query operation name gopal:" + operationName);
            if (operationList.contains(operationName)) {
                isNotSaveOperation = false;
            } else {
                isNotSaveOperation = true;
            }
            invokeEL("#{bindings.EmployeesViewCriteriaQuery.processQueryOperation}",
                     Object.class, QueryOperationEvent.class, queryOperationEvent);
        }

        //Overriden queryListener method
        public void queryListener(QueryEvent queryEvent) {
            System.out.println(" executeQuery " + isNotSaveOperation);
            if (isNotSaveOperation) {
                invokeEL("#{bindings.EmployeesViewCriteriaQuery.processQuery}",
                         Object.class, QueryEvent.class, queryEvent);
            } else {
                isNotSaveOperation = true;
            }

        }

        private Object invokeEL(String expr, Class returnType, Class argType,
                                Object argument) {
            return invokeMethodExpression(expr, returnType,
                                          new Class[] { argType },
                                          new Object[] { argument });
        }

        private Object invokeMethodExpression(String expr, Class returnType,
                                              Class[] argTypes, Object[] args) {
            FacesContext fc = FacesContext.getCurrentInstance();
            ELContext elctx = fc.getELContext();
            ExpressionFactory elFactory =
                fc.getApplication().getExpressionFactory();
            MethodExpression methodExpr =
                elFactory.createMethodExpression(elctx, expr, returnType,
                                                 argTypes);
            return methodExpr.invoke(elctx, args);
        }    
}

*Comments and feedback are most welcomed, Thanks.