UI Tips and Tricks – Country List

This tip introduces a simple pattern used by many AppExchange solutions to manipulate standard layouts. In short, a custom sidebar component is added which contains JavaScript code which manipulates the page at the DOM level. The following simple example shows how the country fields on the account layout can be changed to lists – a common customer request. A Country__c custom object with the Name field populated with country names is required. The Dojo library is also used. Please note, the code below is old and hasn’t been tested recently, I provide this for illustration of the pattern, it certainly won’t be winning any prizes.

So, in the example, Dojo runs the replaceCountryInputs() function when the DOM is ready, this finds the country fields by their ID (Firebug is a good way to browse the page markup), we then remove the original input element and replace with a select element with the same Id. The select element is then populated in JavaScript with the result of a soql query – using the Ajax API. Finally we need to add the inline editing handlers to the new select element – and we’re done.

On the configuration side, the sidebar component must be assigned to the home page layout for relevant users and the setting to enforce display of custom sidebar components must be enabled.

As I’ve said, the use case here isn’t significant it’s the possibility that this technique enables in terms of standard layout manipulation. Be aware that the field ids may be subject to change.


<script src="/js/dojo/0.4.1/dojo.js"></script>
<script src="/soap/ajax/19.0/connection.js" type="text/javascript"></script>
<script type="text/javascript">
var arCountries = getCountries();
var vProcess = replaceCountryInputs();

function replaceCountryInputs()
{
  if (document.getElementById('acc17country')!=null) {
    var defaultVal = document.getElementById('acc17country').value;
    var cInput = swapFieldType('acc17country');
    setCountryListWithDefault(cInput, defaultVal);
  }
  if (document.getElementById('acc18country')!=null) {
    var defaultVal = document.getElementById('acc18country').value;
    var cInput = swapFieldType('acc18country');
    setCountryListWithDefault(cInput, defaultVal);
  }
  if (document.getElementById('acc17_ilecell')!=null) {
    SetupInline('acc17');
  }
  if (document.getElementById('acc18_ilecell')!=null) {
    SetupInline('acc18');
  }
}

function swapFieldType(i)
{
  var cInput = document.getElementById(i);
  var cInputParent = cInput.parentNode;
  cInputParent.removeChild(cInput);
  cInput = document.createElement('select');
  cInput.size = 1;
  cInput.id = i;
  cInput.name = i;
  cInputParent.appendChild(cInput);
  return cInput;
}

function setCountryListWithDefault(i, d)
{
  if(i!=null) {
    if(arCountries.length>0) {
      for(x=0;x<arCountries.length;x++) {
        if(arCountries[x]==d) {
          i.options[x] = new Option(arCountries[x], arCountries[x], false, true);
        } else {
          i.options[x] = new Option(arCountries[x], arCountries[x], false, false);
        }
      }
    } else {
      i.options[x] = new Option('No countries found', 'No countries found', false, true);
    }
  }
}

function SetupInline(prefix) {
  var _element = document.getElementById(prefix + '_ilecell');	
  if (_element) {
    _element.ondblclick = function() {
      var _loaded = false;
      if (!sfdcPage.editMode)
        sfdcPage.activateInlineEditMode();
        
      if (!sfdcPage.inlineEditData.isCurrentField(sfdcPage.getFieldById(_element.id)))
        sfdcPage.inlineEditData.openField(sfdcPage.getFieldById(_element.id));
        
      var idInput = prefix+'country';

      if (document.getElementById(idInput)!=null) {
        var defaultVal = document.getElementById(idInput).value;
        var cInput = swapFieldType(idInput);
        setCountryListWithDefault(cInput, defaultVal);
      }		
    }
  }
}

function getCountries()
{
  sforce.sessionId = getCookie('sid');
  sforce.connection.sessionId=sforce.sessionId;
  var out = [];
  try {
    var queryCountries = sforce.connection.query("Select Id, Name FROM Country__c ORDER BY Name");	
    var countries = queryCountries.getArray('records');
    for(x=0;x<countries.length;x++) {
      out[out.length] = countries[x].Name;
    }					
  } catch(error) {
    alert(error);		
  }	
  return out;
}
dojo.addOnLoad(replaceCountryInputs);
</script>

Comments

  1. Thanks your post helped me solve a challenge…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: