Skip to main content

Overriding Control Hints of a View Object on the fly

I recently came across a use case where the requirement was to fetch Attribute Hints(display width, label etc.) for a View Object(and Entity Object) on the fly from an external system. Let me share a simple possible solution for this specific use case.

A glance at the implementation

The idea is to override ViewRowImpl::createViewRowAttrHints(AttributeDefImpl attrDef) to return a custom implementation of ViewRowAttrHintsImpl class. The same concept has been discussed in one of my previous post sometime back - Decorate UI with view row Attribute's User Interface hints. Please note that, this is the place( custom ViewRowAttrHintsImpl class - LazyViewRowAttrHintsImpl) where we are adding the hook to retrieve the Attribute Hints from third party service.

@Override
protected ViewRowAttrHintsImpl createViewRowAttrHints(AttributeDefImpl attrDef) {
  return new LazyViewRowAttrHintsImpl(attrDef, this);
}

The constructor of LazyViewRowAttrHintsImpl may look like as shown in the following code snippet. Please take a look at th source of LazyViewRowAttrHintsImpl.java to get a feel of the implementation (work space is attached at the end of this post).


 public class LazyViewRowAttrHintsImpl 
                     extends ViewRowAttrHintsImpl {
  
  public LazyViewRowAttrHintsImpl(
           AttributeDefImpl attributeDefImpl,
           ViewRowImpl viewRowImpl) {
    super(attributeDefImpl, viewRowImpl);

    //The following call retrieves AttrHints 
    //from third party service
    //and add the same to Attribute Defn of VO
    decorateWithLazyHints(attributeDefImpl);
  } ...

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 dept.jspx. You may notice that default UI hints ( such as label, field width etc. ) are overridden with values from a dummy service( UIHintsService ).

Comments

Anonymous said…
Can we control the DISPLAY_HINT property as well on the fly?

Say, we want to hide the fields from Model layer, how can we achieve the same?
Jobinesh said…
You can try Overriding ViewRowAttrHintsImpl::getDisplayHint(...)

@Override
public String getDisplayHint(LocaleContext locale) {
return super.getDisplayHint(locale);
}
Please note that, if your UI is human built :-) [I mean, not model driven component like af:query/dynamic table etc.], then you may need to carry this hint to UI.
rendered="#{bindings.DepartmentId.hints.displayHint=='Display'}"
Anonymous said…
Thanks Jobinesh.That helps.

But customer wants to know, why for rendered property we need the EL expression in the jsff/jspx?
Where as we dont do the same for readOnly/disabled property?
Even though, we have dragged and dropped the VO as an af:panelFormLayout and the component af:inputText is VO bound.

Is there any documentation or explanation available to convince the customer?They dont want to put manually a rendered EL expression to all 50 UI fields they have in their JSFF/JSPX?
Jobinesh said…
For readOnly fileds, ADF binding layer is leveraging the feature supplied by JSF :). To make it clear, If you EL bind and input filed's value attribute with a manged bean without setter, the field would be rendered in read only mode by default. However this is applicable only for read only field. This is not carried over other properties such as rendered/disabled properties. There manual intervention is required.
Hey!

Nice post.

I have one problem with it.
I'm using dvt:pivotTable for displaying some data. And pivot table has this good feature of pivoting data around (no shit). :D Inside dvt:pivotTable there is dvt:headerCell and every header cell has its own label. Now I want to dynamically set this label based on data inside that table. I have tried change label property on my view's attribute UI Hints (to some static text) to test it if it works. And it works. Now I want to set label programmatically and I have override createViewRowAttrHints method inside my ViewRowImpl and I have created new class which extends ViewRowAttrHintsImpl and overrides every method (including getLabel) of its super class. On every overriden method I set a breakpoint and here mystery begins. When I run the page none of overriden methods isn't called. If I set breakpoint at constructor it stops ok. Now my question is there any possibility that pivot table works differently with attribute hints? Or am I done something wrong?

Regards
Anonymous said…
Hi.
good sample.
I've tested the sample and works fine with a form but if you drag a table, labels of the columns are painted before that createViewRowAttrHints.
Thanks in advance

JDev version: 11.1.2.1.0
Anonymous said…
Hi Jobinesh,

I've a requirement in which I need to hide one of my VO's fields in the query panel's add_fields when used with one of the view criteria, and it should get displayed with the other view criteria.

We tried to set the rendered property to 'never' for the field in the view criteria, but it doesn't work. Also tried overriding 'createViewRowAttrHints()' and when set the disply hint property as
propMap.put(AttributeHints.ATTRIBUTE_DISPLAY_HINT , AttributeHints.ATTRIBUTE_DISPLAY_HINT_HIDE);

Gives me
javax.el.PropertyNotFoundException: Target Unreachable, '1' returned null
at com.sun.el.parser.AstValue.getTarget(Unknown Source)
at com.sun.el.parser.AstValue.isReadOnly(Unknown Source)

Any ideas to make it work ?

Thanks in Advance.
Jobinesh said…
You can see an example here
http://jobinesh.blogspot.com/2011/07/overriding-display-at-run-time.html
Anonymous said…
Do you know if it is possible to add a custom UI hint to a view object?
Anu said…
Hi Jobinesh,
I have a requirement where i need to change the label of VO attributes dynamically.
With attriibuteDef , I am able to use only getLabel function. Is there any way to set label programtically/dynamically?

Popular posts from this blog

Happy New Year 2018 !

We can't go back and change the beginning, but we always can start where we are and change the ending. Believe in yourself and you will be unstoppable!

Wishing you and your family a very happy new year 2018 !!!

How to set Bind Variable Values at runtime ?

In this post I'm sharing a couple of approaches for programmatically setting bind variables values at run time. This post is an attempt to explain 'When to use what ?'[ In case if you are familiar with 'Bind Variables' in ADF BC, please refer Section 5.10, Working with Bind Variables in Fusion Developer's Guide ]

1. Set the Bind Variable value using RowSet::setNamedWhereClauseParam(...)

You can use use the setNamedWhereClauseParam(...) method on the ViewObject interface (which extends oracle.jbo.RowSet) to set the value for bind variables. Please note this sets the value on default RowSet. In other words, this doesn't have any effect on the secondary RowSets that you/system generates.
ViewObject vo = am.findViewObject("EmployeesView1"); vo.setNamedWhereClauseParam("bindVarDeptId", new Number(10)); vo.executeQuery();
2. Set the Bind Variable value using ViewObject's VariableValueManager::setVariableValue(...)

VariableValueManager Ma…