Hello All,
this post talks about a common requirement - can we apply custom validation in af:query fields ?
yes , we can do that by overriding default query listener of af:query component
What af:query is ?
see- Oracle Docs-af:query
"The query component provides the user the ability to perform a query
based on a saved search or personalize saved searches. The component
displays a search panel with various elements, each of which help the
user to accomplish various tasks."
Follow steps to apply validation on af:query-
- Here i am taking example of Departments table of HR Schema
- First create business components for Departments table
- then create bind variables and a view-criteria in departments view object
- See the view criteria is applied for LocationId, ManagerId and Department Name
- Now create a page and drop criteria with table on page- it will look like this
- Next is to select af:query on page and go to property inspector and copy text of default query listener
- Now create a managed bean and create a custom query listener for af:query
- In this custom query listener , in this example i am checking for negative Location Id and Manager Id, if there is any negative values ,custom method will show a message otherwise default queryListener will be executed
- We can get af:query's components value using 2 methods
First One - Using Bind Variable (getNamedWhereClauseParam)
Second One - Using QueryDescriptor and ConjunctionCriterion - I'm going to explain both methods - see code of custom query listener using first method, two generic methods will be used in this process to invoke expression language and to get BindingContainer of current context
- See the first method to get af:query components value and validate that
- And Second Method using QueryDescriptor is-
- Now Run your application and check it for negative values
/**Method to invoke EL Expression * @param el * @param paramTypes * @param params * @return */ public static Object invokeEL(String el, Class[] paramTypes, Object[] params) { FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory(); MethodExpression exp = expressionFactory.createMethodExpression(elContext, el, Object.class, paramTypes); return exp.invoke(elContext, params); } /**Method to get Binding Container of current page * @return */ public BindingContainer getBindings() { return BindingContext.getCurrent().getCurrentBindingsEntry(); }
/**Custome Query Listener- Using getNamedWhereClauseParam * @param queryEvent */ public void customQueryListener(QueryEvent queryEvent) { String deptName = null; Integer locId = null; Integer mgrId = null; /**Get Iterator of Table*/ DCIteratorBinding iter = (DCIteratorBinding)getBindings().get("DepartmentsView1Iterator"); /**Get ViewObject from Iterator*/ ViewObjectImpl vo = (ViewObjectImpl)iter.getViewObject(); /**Get Bind Variable's Value*/ if (vo.getNamedWhereClauseParam("LocIdBind") != null) { locId = Integer.parseInt(vo.getNamedWhereClauseParam("LocIdBind").toString()); } if (vo.getNamedWhereClauseParam("MgrIdBind") != null) { mgrId = Integer.parseInt(vo.getNamedWhereClauseParam("MgrIdBind").toString()); } if (vo.getNamedWhereClauseParam("DeptNmBind") != null) { deptName = vo.getNamedWhereClauseParam("DeptNmBind").toString(); } /**Check for Negative values*/ if ((locId != null && locId < 0) || (mgrId != null && mgrId < 0)) { FacesMessage msg = new FacesMessage("Id Value can not be negative"); msg.setSeverity(FacesMessage.SEVERITY_ERROR); FacesContext.getCurrentInstance().addMessage(null, msg); } else { /**Execute default query listener with help of invokeEL method*/ invokeEL("#{bindings.DepartmentsViewCriteriaQuery.processQuery}", new Class[] { QueryEvent.class }, new Object[] { queryEvent }); } }
/**Custom Query Listener-Using QueryDescriptor * @param queryEvent */ public void customqueryProcess(QueryEvent queryEvent) { String deptName = null; Integer locId = null; Integer mgrId = null; /**Reference-Frank Nimphius Example- ADF Code Corner * http://www.oracle.com/technetwork/developer-tools/adf/learnmore/85-querycomponent-fieldvalidation-427197.pdf * */ QueryDescriptor qd = queryEvent.getDescriptor(); ConjunctionCriterion conCrit = qd.getConjunctionCriterion(); //access the list of search fields List<Criterion> criterionList = conCrit.getCriterionList(); //iterate over the attributes to find FromDate and ToDate for (Criterion criterion : criterionList) { AttributeDescriptor attrDescriptor = ((AttributeCriterion)criterion).getAttribute(); if (attrDescriptor.getName().equalsIgnoreCase("DepartmentName")) { deptName = (String)((AttributeCriterion)criterion).getValues().get(0); } else { if (attrDescriptor.getName().equalsIgnoreCase("LocationId")) { locId = (Integer)((AttributeCriterion)criterion).getValues().get(0); } } if (attrDescriptor.getName().equalsIgnoreCase("ManagerId")) { mgrId = (Integer)((AttributeCriterion)criterion).getValues().get(0); } } if ((locId != null && locId < 0) || (mgrId != null && mgrId < 0)) { FacesMessage msg = new FacesMessage("Id Value can not be negative"); msg.setSeverity(FacesMessage.SEVERITY_ERROR); FacesContext.getCurrentInstance().addMessage(null, msg); } else { /**Process default query listener*/ invokeEL("#{bindings.DepartmentsViewCriteriaQuery.processQuery}", new Class[] { QueryEvent.class }, new Object[] { queryEvent }); } }
Cheers- Download Sample App Happy Learning :-)
Very good this post and very useful.
ReplyDeleteIn the criteria for the item type to date between option,
simply select the indices of them as 0 and 1 for the name of the desired field.
if (attrDescriptor.getName().equalsIgnoreCase("MyDateFieldName")) {
beginDate =(Date)((AttributeCriterion)criterion).getValues().get(0);
endDate =(Date)((AttributeCriterion)criterion).getValues().get(1);
}
Thanks Natan but I didn't understand the code part
DeleteIs this additional info when using between operator for dates ?
Ashish
well done
ReplyDeleteExcellent post Asish. I have a related question to af:query in OTN forum: https://community.oracle.com/message/14276846 Thanks!
ReplyDelete