Integrating Ext JS Combo Boxes with SalesForce.com

We’re working with a customer to integrate an Ext JS 4 UI with SalesForce.com and have run into a number of interesting challenges.

One of the issues that we ran into pertains to how remote Ext JS 4 combo boxes transmit query data to the back-end in order to perform incremental searches. Out of the box, whatever the user types into the combo box is transmitted over the uri, e.g. getmydata.aspx?query=somethingITypedIntoAComboBox. The problem is that the salesforce transport mechanism that we’re using only carries forward data passed in the http header, ignoring everything passed on the url.

We wound up modifying the combo box to transmit query data over a Store’s proxy header by setting up a combo box listener that dynamically changed the related store’s proxy header as illustrated below:

{
 xtype: 'combo',
 listeners: {
   beforequery: function(queryPlan,eopts) {
       this.store.on('beforeload', function(store,operations,eopts) {
          Ext.apply(store.proxy.headers, { 
                      query:queryPlan.query 
          });
       });
   },
   afterquery: function(queryPlan,eopts) {
      this.store.un('beforeload');
      store.proxy.headers.query=null;
   }
 },
 store: s,
 displayField: 'Name',
 valueField: 'Id',
 typeAhead: false,
 hideLabel: true,
 hideTrigger:true,
 anchor: '100%',
 listConfig: {
  loadingText: 'Searching...',
  emptyText: 'No matching posts found.',

  // Custom rendering template for each item
  getInnerTpl: function() {
    return '<h3>{Name}</h3>';
  }
 },
 pageSize: 10
}

The underlying Store used the SalesForce.com services proxy:

 Ext.define('MyApp.store.MyStore', {
  extend: 'Ext.data.Store',
  storeId: 'MyStore',
  idProperty: 'Id',
  fields: [ { name: 'Id' } , {name: 'Name'}, {name: 'BillingCity'}],
  proxy: {
    type: 'rest',
    url: '/services/proxy',
    headers: {
      'SalesforceProxy-Endpoint' :  serverURL + PATH,
      'Authorization': 'OAuth ' + SESSION_ID
    }
  }
 });

The serverUrl and session ID are dynamically output at runtime from SalesForce’s apex architecture:

<apex:page docType="html-5.0" sidebar="false" showHeader="false" 
    standardStylesheets="false" cache="true" applyBodyTag="false">
 
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="{!URLFOR($Resource.ExtJS,'ext-all.js')}"></script>
    <link rel="stylesheet" href="{!URLFOR($Resource.ExtJS,'ext-theme-neptune-all.css')}"/>
    <script type="text/javascript">
      var SESSION_ID = '{!$Api.Session_ID}';
      var serverURL = '{!SUBSTITUTE(SUBSTITUTE(LEFT($Api.Partner_Server_URL_210, FIND( '/services', $Api.Partner_Server_URL_260)), 'visual.force', 'salesforce'), 'c.', '')}';
      // If its a mydomain enabled org, the mydomain name needs to be stripped 
      var splitURL = serverURL.split(/\./g);
      if(splitURL.length==4) {
          splitURL[0] = 'https://';
          serverURL = splitURL.join(".").replace('.','');
      }
     
      var PATH = 'services/apexrest/XN/Account';
   </script>

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