Saturday, January 22, 2011

Customizing the <af:query> component display by overriding CriteriaItemAttributeHints

More granular control on the display of af:query is a much awaited feature by the ADF community. Good news is that, 11gR1(11.1.1.4.0)[ aka 11gR1PS3 ] release comes along with new API on ViewObjectImpl - public AttributeHints getCriteriaItemAttributeHints(ViewCriteriaItem vci) - which may help you to hook your custom logic to control the 'run time' display behavior of af:query built using ViewCriteria.

I'm sharing simple example built based on the above concept. This example would display 'DepartmentName' in a 'shortened field' when displayed inside the af:query whereas the same field would be displayed in the normal size when displayed out side of af:query.


A glance at the implementation

This example overrides the DepartmentsViewImpl::getCriteriaItemAttributeHints(ViewCriteriaItem vci) to return customized AttributeHints as shown in the following code snippet

/**
* By default return null. Subclasses may override to return
* custom AttributeHints implementation for the given criteria item.
*/
@Override
public AttributeHints getCriteriaItemAttributeHints(ViewCriteriaItem vci) {
  if (vci != null &&
    vci.getAttributeDef().getName().equals("DepartmentName")) {
    return getCustomCriteriaItemAttributeHints(vci);
  }
  return super.getCriteriaItemAttributeHints(vci);
}
private AttributeHints getCustomCriteriaItemAttributeHints(ViewCriteriaItem vci) {
  AttributeHints cutomAttributeHints = null;
  String vciName = vci.getAttributeDef().getName();
  if ((cutomAttributeHints = hintsMap.get(vciName)) == null) {
    cutomAttributeHints = new CustomCriteriaItemAttributeHintImpl(vci);
    hintsMap.put(vciName, cutomAttributeHints);
  }
  return cutomAttributeHints;
}


You can take a look at the model.CustomCriteriaItemAttributeHintImpl (workspace is attached at the end of this post) to get a feel of the custom AttributeHints implementation. This class is sub classed from a generic CriteriaItemAttributeHintAdaptor class, which gives default implementation for all the methods required as per the contract set by the AttributeHints. Override the methods of your choice to add custom 'UI hints' based on the use case you are working with.

The current example overrides AttributeHints::getDisplayWidth(LocaleContext locale) using CustomCriteriaItemAttributeHintImpl class to provide 'reduced' field width for 'DepartmentName' field when displayed inside a query panel (which is built using ViewCriteria).

@Override
public int getDisplayWidth(LocaleContext locale) {
  ViewCriteriaItem vci = this.getViewCriteriaItem();
/** 
 * String HINT_NAME_DISPLAY_WIDTH_FOR_QUERY is the custom property defined at
 * DepartmentName attribute level to hold custom field width value 
 */
  Object fieldWidth =
    vci.getAttributeDef().getProperty(HINT_NAME_DISPLAY_WIDTH_FOR_QUERY);
  if (fieldWidth != null) {
    return Integer.parseInt((String)fieldWidth);
  }
  return super.getDisplayWidth(locale);
}


You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS3 + HR Schema]

How to run this sample?

Please run the test.jspx. You may notice that 'DepartmentName' field is smaller in size when displayed inside the search panel at run time.

4 comments:

TJ said...

Hi Jobines,

Thanks for the post. I want to know can we mark a view criteria item as readOnly also means user not able to change the value in viewcriteria for a particular item.

Jobinesh said...

TJ,
Its not supported as of now

Anonymous said...

Hi Jobinesh,
its a quite helpful post.
If we have a checkbox in the search panel and we want the label to be displayed on the RHS instead of LHS.. is this possible.
Please provide some pointers.

Thanks
Swetha

Anonymous said...

Hi Jobinesh,
My attribute is input text by default and its length in DB is 250 Chars. So when i want to reduce the length and width i will change the display width and height property of the attribute. it works fine in BC tester and pages. But when i use the same field in ViewCriteria and render as query panel able to change the width and height is not reflected. Even tried your sample given here by overriding getDispalyHeight() method. Can you help me with this?

Thanks,
Deena.