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
/**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();
}
- See the first method to get af:query components value and validate that
/**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 });
}
}
- And Second Method using QueryDescriptor is-
/**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 });
}
}
- Now Run your application and check it for negative values