Bridgeline Digital Logo
Menu

JavaScript Remoting with OrchestraCMS

Making JavaScript Remote Requests using OrchestraCMS

OrchestraCMS provides a JavaScript function and Service Interface to make an AJAX request from an OrchestraCMS page to your custom apex code in Salesforce.  This is the supported method of making JavaScript AJAX requests within OrchestraCMS pages, and should be used instead of the Visualforce.remoting function and any <apex> Visualforce components that make remote requests.

There are two main options available: one for performing DML – allowing you to create or update records in Salesforce – or one in read-only mode, allowing more data to be retrieved from Salesforce.

The example below allows you to retrieve the logged in user's name (or, in the case of an unauthenticated page, the site guest user) and has a form that will allow the creation of a Lead:

  • Example code that could be included in your Apex Class
// cms.ServiceInterface provides the apex remoting implementation, class must be global
global with sharing class MyServiceClass implements cms.ServiceInterface {
  private Map<String, String> parameters;
  private String action;
  private System.JSONGenerator response;

  // getType must be implemented, alway return YourClassName.class
  public System.Type getType(){  
    return MyServiceClass.class;
  }

  // executeRequest performs the execution of your custom code
  // to return a JSON response to your JavaScript callback handler.
  // The "action" parameter is used to determine which code block to execute,
  // allowing the implementation of many different actions within the same class.
  // This method must be global.
  global String executeRequest(Map<String, String> p) {
    // executeRequest should start with these 3 lines
    response = System.JSON.createGenerator(false);
    response.writeStartObject(); 
    this.parameters = p;

    try {
      // Get value from object action
      action = p.get('action');
      if (action == 'getUserName') {

        // Return a random user name as a JSON value
        String loggedInUserID = UserInfo.getUserId();
        String userName = [SELECT Name FROM User WHERE Id =: loggedInUserID LIMIT 1].Name;

        // Write the response data
        response.writeBooleanField('success', true);
        response.writeStringField('userName', userName);

      } else if (action == 'saveNewLead') { // Create a new Lead based on our form data and 
                                            // return the new Lead ID

        // Get the parameters passed in our XHR request
        String companyName = p.get('companyName');
        String firstName = p.get('firstName');
        String lastName = p.get('lastName');
        String emailAddress = p.get('emailAddress');
        String phoneNumber = p.get('phoneNumber');
         
        // We want to use error handling to catch potential errors with the form data 
        //   and return an appropriate response
        // OrchestraCMS does not handle catching custom errors and you may receive an 
        //   unexpected response in your XHR request 
        try {

          // Create and insert a new lead with the form submission data
          Lead theLead = new Lead(Company = companyName, FirstName = firstName, 
                                  LastName = lastName, Email = emailAddress, Phone = phoneNumber);
          insert theLead;

          // Write the response data
          response.writeBooleanField('success', true);
          response.writeStringField('leadID', theLead.Id);

        } catch(DmlException e) {

          // An error occurred trying to save our data. We'll write the error message 
          //   to our response
          response.writeBooleanField('success', false);
          response.writeStringField('error', e.getMessage());
        }

      } else {

        // An XHR request was made with an unsupported action
        response.writeBooleanField('success', false);
        response.writeStringField('message', 'Unsupported action');

      }
    } catch (exception e) {

      // There was a generic error
      response.writeBooleanField('success', false);
      response.writeStringField('message', 'Error occurred');

    }

    // Close the JSON response variable and return it
    response.close();
    return (response.getAsString());

  }

}
  • Example form code that can be used on your Page Template
<form name="leadForm" id="leadForm" action="" method="post">
   <table>
      <tbody>
         <tr>
            <td>Company Name: </td>
            <td><input type="text" name="companyName" id="companyName" value="" /></td>
         </tr>
         <tr>
            <td>First Name: </td>
            <td><input type="text" name="firstName" id="firstName" value="" /></td>
         </tr>
         <tr>
            <td>Last Name: </td>
            <td><input type="text" name="lastName" id="lastName" value="" /></td>
         </tr>
         <tr>
            <td>Email Address: </td>
            <td><input type="text" name="emailAddress" id="emailAddress" value="" /></td>
         </tr>
         <tr>
            <td>Phone Number: </td>
            <td><input type="text" name="phoneNumber" id="phoneNumber" value="" /></td>
         </tr>
         <tr>
            <td>&nbsp;</td>
            <td><input type="submit" name="submit" id="submit" value="Save Lead" /></td>
         </tr>
      </tbody>
   </table>
</form>
  • Example code that could be used on your Page Template or in a Static Resource
// Request to retrieve data from Salesforce through OrchestraCMS
$(document).ready(function() {
   // Create the JSON object to send to the server with our data
   var data = { service: 'MyServiceClass',  // Name of the apex class to invoke 
                action: 'getUserName'       // Value of the action parameter used in the class
              };

   // Handle response of a successful ajax call using a callback function
   var callBackHandler = function(json)
      {
         if (json.success) {
            // Process any json response data here using json.success or json.my_parameter
            // We should have a valid json.userName here
         } else {
            // Process any error response data here
            // We did not get a valid json.userName
         }
      }

   var options = { cb: callBackHandler,
                   readonly: true  // Set to true if action does not perform DML
                                   // Set to false if action performs DML operation
                 };

   doServiceRequest(data, options);  // Global function to perform remoting request
});
 
// Request to submit data to Salesforce through OrchestraCMS
$('#submit').on('click', function() {
   // Create the JSON object to send to the server with our data
   var data = { service: 'MyServiceClass',  // Name of the apex class to invoke
                action: 'saveNewLead',      // Value of the action parameter used in the class
                companyName: $('#companyName').val(),  //  Additional parameters used with the action
                firstName: $('#firstName').val(),
                lastName: $('#lastName').val(),
                emailAddress: $('#emailAddress').val(),
                phoneNumber: $('#phoneNumber').val()
              };

   var callBackHandler = function(json)
      {
         if (json.success) {
            // Process any json response data here using json.success or json.my_parameter
         } else {
            // Process any error response data here
         }      
      }

   var options = { cb: callBackHandler,
                   readonly: false  // Set to false if action performs DML operation
                                    // Set to true if action does not perform DML
                 };

   doServiceRequest(data, options);  // Global function to perform remoting request
});

Sample code that can be run from the Chrome Developer Console to mimic testing

//
// Sample code that can be input into the browser console as is to verify the class is working
//
var data = { service: 'MyServiceClass',  // Name of the apex class to invoke
             action: 'saveNewLead',      // Value of the action parameter used in the class
             companyName: $('#companyName').val(),  //  Additional parameters used with the action
             firstName: $('#firstName').val(),
             lastName: $('#lastName').val(),
             emailAddress: $('#emailAddress').val(),
             phoneNumber: $('#phoneNumber').val()
           };

var callBackHandler = function(json)
{
   if (json.success) {
      // Process any json response data here using json.success or json.my_parameter
      console.log('Lead generated successfully with ID of: '+json.leadID);
   } else {
      console.log('Failure generating lead ID because: '+json.error);
   }
}

var options = { cb: callBackHandler,
                readonly: false  // Set to false if action performs DML operation
                                    // Set to true if action does not perform DML
              };

doServiceRequest(data, options);  // Global function to perform remoting request