Search This Blog


Monday, October 17, 2011

ADF: Get social security numbers right

A common development use case is to guide users when working with input fields that require a specific input format. For example, credit card and social security number fields use character delimiters that you may want to enforce on a field. The following sample uses JavaScript to add a defined delimiter character according to a defined character.
The American social security pattern is defined as xxx-xx-xxxx. Users that type 123456789 should have the input automatically corrected to 123-45-6789 while they type. Also, the field should be protected from character input and input length larger than the provided pattern.
<af:inputText label="Social Security Number" id="it1"
With the above configuration, the handleNumberFormatConversion method is called for each key stroke in the input field. Additional arguments provided to the function are the input pattern and the character delimiter.
The JavaScript code that is addressed by the clientListener on the InputText is shown below:
// JavaScript function that applies a specific format
// to numeric input. The pattern argument defines the
// input mask, e.g. xxx-xx-xxxx. The delimiter defines
// the delimiter character to add to the user input based
// on the pattern
function handleNumberFormatConversion(pattern, delimiter){
  return function(evt){
       var inputField  = evt.getCurrentTarget();
       var keyPressed = evt.getKeyCode();
       var oldValue   = inputField.getSubmittedValue();             
       //keycode 48-57  are keys 0-9
       //keycode 96-105 are numbpad keys 0-9
       var validKeys = new Array(48,49,50,51,52,53,54,55,
         var numberKeys = new Array(48,49,50,51,52,53,54,55,
       var isValidKey = false;
       for (var i=0; i < validKeys.length; ++i){
          if (validKeys[i] == keyPressed) {
               isValidKey = true;
         //key is valid, ensure formatting is correct
         var isNumberKey = false;
         for (var n=0; n < numberKeys.length; ++n){
           if(numberKeys[n] == keyPressed){
             isNumberKey = true;
           //if the user provided enough data, cancel
           //the input
           var formatLength = pattern.length;
           if(formatLength == oldValue.length){
           //more values allowed. Check if delimiter needs to
           //be set          
             //if the date format has a delimiter as the next
             //character, add it
             if(pattern.charAt(oldValue.length)== delimiter){
               oldValue = oldValue+delimiter;     
         //key is not valid, so undo entry
The sample is for number only input. However, changing it for character or mixed input is not difficult to do. Note however that you can't use this with af:inputDate component because this component doesn't work well when setting String formatted values as the value property. (At least my debugging showed this)