Skip to main content

Decorate UI with view row Attribute's User Interface hints

This post discusses the possibility of using custom view row attribute hints to decorate your view layer. For example, let us take an Employee table, the use case requirement is to display red icon in a column if the salary is greater than 10000, green icon for all other cases. Please see the below screen shot for reference.



Apparently there are multiple ways to achieve this. The approach I followed here is through custom view row attribute hints implementation. The idea is inspired by an earlier post from Steve.

A glance at the implementation

Implementation is very simple, Override ViewRowAttrHintsImpl::getHint(...) by sub classing ViewRowAttrHintsImpl. Please note that ViewRowAttrHintsImpl::getHint(..) will get invoked whenever the binding layer identifies any custom hints in the EL.

The below implementation overrides the default behavior of getHint(...) to return different icons based on the salary, for the custom hint 'statusIcon'.

Map iconMap = new HashMap<String, String>() {
  {
    put("LowSalIcon", "images/lowSalIcon.gif");
    put("HighSalIcon", "images/highSalIcon.gif");

  }
};

@Override
public String getHint(LocaleContext locale, String sHintName) {

if ("statusIcon".equals(sHintName)) {
    Number salary = (Number)getViewRow().getAttribute("Salary");

    if (salary != null && salary.getValue() > 10000)
    return iconMap.get("HighSalIcon");
    else
    return iconMap.get("LowSalIcon");
}
return super.getHint(locale, sHintName);
}

You can wire this custom ViewRowAttrHintsImpl to a ViewRowImpl by overriding
ViewRowImpl::createViewRowAttrHints(AttributeDefImpl attrDef)

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

Now, you may need to refer this custom hint(statusIcon) from the UI using EL binding. The below jsf snippet shows how this is done when you use table.

<af:column sortProperty="Status" sortable="false"
     headerText="#{bindings.EmployeesView11.hints.Status.label}"
     id="c7">
<af:image source="#{row.bindings.Status.hints['statusIcon']}"
      id="ai1"/>
</af:column>

How does it work?

While rendering each status column for a table, EL #{row.bindings.Status.hints['statusIcon']} trigger EmployeesViewRowAttrHintsImpl::getHint() method, which in turn return the desired icon.

If you use form, then use below EL binding to refer the custom hint

<af:image source="#{bindings.Status.hints.statusIcon}" id="i2" shortDesc="status"/>

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

Learn More ...

There are many more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/10/oracle-adf-real-world-developers-guide.html

Comments

HusainD said…
Great post Jobinesh. An interesting idea indeed.

I am wondering however if its a good idea to put icon names (and folder location) in VO.
Would it be a better idea for the VO to retun state (high, medium, low) and let the UI switch icons accordingly?

Thanks,
Husain
Jobinesh said…
thanks...
I agree if the icon name is set as a VO attribute or if the VO contains some client specific code(say html snippet/Swing classes). That said however, the above sample is more like extending Control Hints for VO, so valid where you have model driven approach to build your UI
Anonymous said…
Hi Jobinesh,

in our application we use dvt:gauge (LED-Type) to display status icons like in your approach.
The advantage in my point of view is that dvt:gauge has build-in functionality to declare treshholds and according colors.

regards
Peter
Jobinesh said…
Peter,
You are right! your approach seems to be better from this specific use case's perceptive. Thanks for sharing this tip.
Anonymous said…
Amazing issues here. I'm very glad to look your article. Thanks a lot and I am taking a look ahead to touch you. Will you kindly drop me a mail?
my webpage - online portfolio

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…