Fun ADF challenge: showing the previous field in the tool tip for each form field

The other day I received the following email:

[…] thanks for your ADF articles. I will need an urgent technical help. It would be highly appreciated if you help me.

I have around 20 input text boxes in my page which shows all the current values when I open popup.

I have a hashmap which has column name and old value. Based on this I will need to show a tooptip like if I click a text box it should show a tool tip with old value.

How do I show the tool tip (shortDesc) for each text box dynamically using that hashmap?

Thank you so much.

Normally I would not respond to a query like this – I am really too busy most of the times to act as someone’s personal helpdesk. However, this was just a nice little challenge to start the day with. So, against my better judgement I responded with a few lines explaining the approach I would take. Followed by an email that had an ADF application as attachment with this functionality implemented.

Image

In this article, I will briefly explain how I went about this. At the end, the ADF application is attached as well.

The ADF application I created to demonstrate the functionality requested is simple and straightforward. It consists of:

  • (Bean) Class Employee – that represents an Employee entity with fields like name, function and salary
  • The PreviousValuesHolder bean (session scope) that implements the Map interface and contains an HashMap with the most recent old values for the fields in the form
  • The OldValueCollector – a request scope bean that contains a validator method that records the old value for any field that is changed in the PreviousValuesHolder bean
  • the EmployeeForm.jspx page that displays the form based on the EmployeeBean

Image

The faces-config.xml file contains the bean definitions for the three beans mentioned before:

  <managed-bean>
    <managed-bean-name>employeeBean</managed-bean-name>
    <managed-bean-class>nl.amis.hr.view.Employee</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
  <managed-bean>
    <managed-bean-name>previousEmployeeValuesHolderBean</managed-bean-name>
    <managed-bean-class>nl.amis.hr.view.PreviousValuesHolder</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
  <managed-bean>
    <managed-bean-name>oldValueCollectorBean</managed-bean-name>
    <managed-bean-class>nl.amis.hr.view.OldValueCollector</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>valueHolder</property-name>
      <property-class>nl.amis.hr.view.PreviousValuesHolder</property-class>
      <value>#{previousEmployeeValuesHolderBean}</value>
    </managed-property>
  </managed-bean>

Notice how the previousEmployeeValuesHolderBean is injected into the oldValueCollectorBean.

The key method in the class OldValueCollector, underpinning the oldValueCollectorBean is the fieldChange method. This method is configured as validator method for all fields in the EmployeeForm.jspx page:

public void fieldChange (ValueChangeEvent event) {
valueHolder.put(event.getComponent().getId(), event.getOldValue());
}

The method records the old value for the component whose value change is reported to fieldChange in the valueHolder bean – which is the injected previousEmployeeValuesHolderBean.

The fields in the form in the EmployeeForm.jspx page are linked to all three beans:

  • employeeBean to retrieve their value from and record the changed value to
  • previousEmployeeValuesHolderBean to read the previous value from to display in the tooltip (via the shortDesc attribute)
  • oldValueCollectorBean (via the valueChangeListener) to report a change in value to and have that change record in the previousEmployeeValuesHolderBean
<af:inputText label="Name" id="name" value="#{employeeBean.name}" shortDesc="Previous Value: #{previousEmployeeValuesHolderBean['name']}" valueChangeListener="#{oldValueCollectorBean.fieldChange}"/>;

Note how the id of the form elements should match with the value used in the EL expression in the shortDesc attribute (#{previousEmployeeValuesHolderBean[‘id_of_form_element’]}”).

Resources

Download the JDeveloper 11g PS3 application HrmWithPreviousValue: HrmWithPreviousValue.zip