21 May 2013

Switching Lists of Values

Some time ago I blogged about a feature when a VO's attribute can have multiple LOVs and showed how to switch to the desired LOV depending on the value of another VO's attribute. I this post I'm going to use this technique again, but I'm going to choose the LOV for the attribute depending on its value, on the value of the attribute for which the LOV is defined.
Let's consider a simple use-case: We have an input field for a currency code. When a user inputs a currency code, we have to show corresponding currency description near the input field. So, it should look like this:

The implementation of this use-case is pretty obvious - we have to define a LOV for the currency attribute and set autoSubmit=true for the inputText.

<af:inputText value="#{bindings.Ccy.inputValue}"
              shortDesc="#{bindings.Ccy.hints.tooltip}" id="it1"
    <f:validator binding="#{bindings.Ccy.validator}"/>

<af:outputText value="#{bindings.CurrencyName.inputValue}" id="ot1"/>

Actually besides a symbolic code like USD and EUR a currency has a numeric code like 840 and 978. Sometimes a user prefers to input a symbolic code and sometimes a numeric one. Let's allow users to input whatever they want - either symbolic or numeric code, and we will take care of both and show correct currency description. We are going to add to the VO a transient updatable attribute with two LOVs. A user inputs a value of this attribute and depending on the value's type (string or numeric)  we'll use a corresponding LOV. The first LOV looks for the currency description by symbolic code and the second one by numeric code.

The LOV for the symbolic code (Ccy):

And the LOV for the numeric code (Nbuid):

In order to switch between LOVs we use additional transient attribute CcyLovSwitcher:

And the value of the CcyLovSwitcher is going to be some Groovy expression:

The expression adf.object.ccyLovName refers to the method of our custom ViewRowImpl  class:

public String getCcyLovName() {

  //Return a corresponding LOV's name
  //depending on the value's type - string or numeric

  String looukupValue = getCcyLookup();    
  if (isNumeric(looukupValue))
      return "LOV_CcyLookupByID";
      return "LOV_CcyLookupByCcy";


//Check whether the value is numeric
private boolean isNumeric(String value) {
  return value.matches("\\d+");

And now our users are free to input either symbolic or numeric currency code:

That's it!

No comments:

Post a Comment

Post Comment