Instant field conversion – Rapid Data entry and SMS Speak converter – using ADF Faces PPR with Customer JSF Converters

While preparing for my paper Getting the most AJAX out of ADF Faces – Developing really rich web applications for the upcoming ODTUG 2007 Kaleidoscope conference, I dabbled a little deeper in various aspects of the declarative AJAX (partial page rendering) functionality in ADF Faces. I ran into a nice little application of this feature, that could actually be quite useful to end users.

In short: using a customer converter on a text input field with autoSubmit=true and the field in its own partialTriggers attribute, we can easily turn user input into something else immediately after the user tabs out of the field. This would allow us to provide, for example:

  • SMS Speak to normal language conversion (for rapid text entry) (or vice versa, for the older generations)
  • rapid code entry – for example enter ISO Country Code and turn it into the full Country Name
  • Spelling Corrector on text areas
  • Language Translator (turn to German or French, for example using BableFish)

And many more nice little productivity enhancing pieces of functionality.

Instant field conversion - Rapid Data entry and SMS Speak converter - using ADF Faces PPR with Customer JSF Converters pprautoconversion

One of the really nice things about all this, is the relative ease of implementation. Not a single letter of JavaScript is required, and only very straightforward Java programming and a little bit of
configuration.

The steps

  1. create a custom converter that turns the value entered by the user into whatever value it should have
  2. register that converter in the faces-config.xml file
  3. go to the InputText field that we want to have instant conversion added to.
  4. make sure you specify a value for the id attribute
  5. set autoSubmit to true for the component
  6. add its own id value to the partialTriggers attribute
  7. add an f:converter child element to the InputText. Set its converterId attribute to the custom converter registered in step 2.

 

That’s it. Now you can run the page and see the instant conversion in action.

Demonstration

Suppose we have a country input field in a JSF page. It’s a simple inputText where the user can enter the name of the country of say a customer. However, we will provide a short-cut for our end users: they can simply type the two letter ISO country code – for example us, uk, nl and de – and have the application turn that entry into the full country name. We need a CountryConverter – that turns the two letter code into the full name -, add that converter to the country field, set autoSubmit to true – to initiate the PPR cycle that will also activate the CountryConverter and include the id of the country field in its own partialTriggers attribute.

The CountryConverter class – a very simple rendition that only supports a few countries – could look like this:

package nl.amis.crm.model;

import java.util.HashMap;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;


public class CountryConverter implements Converter {

    Map countries = new HashMap(10);
    public CountryConverter() {
        countries.put("us","United States of America");
        countries.put("nl","The Netherlands");
        countries.put("fr","France");
        countries.put("uk","United Kingdom");
        countries.put("de","Germany");
        countries.put("in","India");
    }
    
    public Object getAsObject(FacesContext facesContext, 
                              UIComponent uiComponent, String string) {
        String country = string;
        if (country.length()==2 && countries.containsKey(country)) {
          country= (String)countries.get(country);
        }
        return country;
    }

    public String getAsString(FacesContext facesContext, 
                              UIComponent uiComponent, Object object) {
        return object.toString();
    }

}

The registration of this converter in faces-config.xml file:

<converter>
   <converter-id>CountryConverter</converter-id>
   <converter-class>nl.amis.crm.model.CountryConverter</converter-class>
</converter>

Now the configuration of this converter on the inputText element:

<af:inputText  id="country" label="Country" partialTriggers="country" autoSubmit="true">
  <f:converter converterId="CountryConverter"/>
</af:inputText>

And that is all we need, we are ready to run this little nugget.

if you enter a value such as us or uk or nl in the Country field and tab out of it, the autosubmit + converter + PPR action will update the field near-instanteously with the full country name.

Instant field conversion - Rapid Data entry and SMS Speak converter - using ADF Faces PPR with Customer JSF Converters pprautoconversion

SMS Speak Converter – From CU and L8R to See You and Later

Using this mechanism the possibilities for making life easier for our end users are virtually limitless. And an abundance of Converters especially to serve this need could become available. Let’s look at an another simple example for applying this idea. Suppose we have a text area where our end users can write summaries of telephone conversations they have had with customers or write any sort of report. The de facto steno language of today is probably SMS Speak (see for example http://sites.ninemsn.com.au/minisite/web2sms/help/smsdict.asp for some of the most popular terms in SMS Speak).

Instant field conversion - Rapid Data entry and SMS Speak converter - using ADF Faces PPR with Customer JSF Converters smsspeak2

 

The steps are the same as before:

  • Develop Converter class
  • Register Converter
  • Configure inputText component

Converter Class:

package nl.amis.crm.model;

import java.util.HashMap;
import java.util.Map;

import java.util.Set;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class SMSSpeakConverter implements Converter {

    Map smsTranslation = new HashMap(10);
    public SMSSpeakConverter() {
        smsTranslation.put("AFAIK","as far as I know");
        smsTranslation.put("ASAP","as soon as possible");
        smsTranslation.put("A3","anytime, anywhere, anyplace");
        smsTranslation.put("CU","see you");
        smsTranslation.put("MTE","my thoughts exactly");
        smsTranslation.put("10Q","thank you");
    }
    
    public Object getAsObject(FacesContext facesContext, 
                              UIComponent uiComponent, String string) {
        String text = string;
        for (String key:(Set<String>)smsTranslation.keySet()) {
          text = text.replaceAll(key.toLowerCase(), (String)smsTranslation.get(key));
        }
        
        return text;
    }

    public String getAsString(FacesContext facesContext, 
                              UIComponent uiComponent, Object object) {
        return object.toString();
    }

}

Registration in faces-config.xml:

<converter>
   <converter-id>SMSSpeakConverter</converter-id>
   <converter-class>nl.amis.crm.model.SMSSpeakConverter</converter-class>
</converter>

InputText component:

<af:inputText label="Summary" id="summary" partialTriggers="summary"  autoSubmit="true" 
              columns="50" rows="6">
  <f:converter converterId="SMSSpeakConverter" />
</af:inputText>

And run the application with the above shown effect.