- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
How to Write Smart GlideAjax Quickly
Contents
Part 1 - The Approach
Part 2 - Reusability
Part 3 - Extending Functionality
Part 4 - Implementing GlideAjax with 1 LOC
Extending Functionality
In Part 2, we created a re-usable Script Include for getting a field from any given Reference field, to be called by a Client Script.
Today, we are going to extend this to handle multiple fields.
Why Stop At One - Handle for Multiple Fields
Let's first take a look at our existing function from ShackleFreeAjax
getPairValueDisplay: function(table, sysId, fieldName) {
var gr = new GlideRecordSecure(table);
if (gr.get(sysId)) {
return {
value: gr.getValue(fieldName),
displayValue: gr.getDisplayValue(fieldName)
}
}
} ;
Lets extend this Function to handle multiple field names instead of just one.
In order to do this, we will need to do the following
- Accept multiple field names as a parameter
-
- Lets use an Array
- Return field values and display for multiple fields
-
- Lets store the pairs in a struct
We will add plurals to our function name to make it clear that the output is different.
getPairValuesDisplays: function(table, sysId, fieldNames) {
var fieldsPairValues = {}; // New Structure to contain all our field values and displays
var gr = new GlideRecordSecure(table);
if (gr.get(sysId)) {
//Iterate through all our field names
for(var f in fieldNames) {
var fieldName = fieldNames[f];
var value = gr.getValue(fieldName);
if (value != null) { //Value is null if user has no read access
var fieldValueDisplay = {
value: gr.getValue(fieldName),
displayValue: gr.getDisplayValue(fieldName)
};
fieldsPairValues[fieldName] = fieldValueDisplay; //Add field data
}
}
}
return fieldsPairValues;
},
We will also need to make some changes to our client data handler function.
Lets keep separations of concerns here -
- We will now expect a comma separated list of field names
-
- This will have to be turned into an Array
- Call a different function
ajaxClientDataHandler: function() {
//Get data from the form
var tableName = this.getParameter('sysparm_tablename');
var sysId = this.getParameter('sysparm_sysid');
//Handle multiple field names
var commaSeperatedFields = this.getParameter('sysparm_fieldnames');
var fieldNames = commaSeperatedFields.split(",");
//Setup data to return to form
var answer={};
//Do server side stuff
answer = this.getPairValuesDisplays(tableName, sysId, fieldNames);
//Encode data to send back to the form
return new JSON().encode(answer);
},
Out new Script Include, WhyStopAtOneAjax now looks like this
var WhyStopAtOneAjax = Class.create();
WhyStopAtOneAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
ajaxClientDataHandler: function() {
//Get data from the form
var tableName = this.getParameter('sysparm_tablename');
var sysId = this.getParameter('sysparm_sysid');
//Handle multiple field names
var commaSeperatedFields = this.getParameter('sysparm_fieldnames');
var fieldNames = commaSeperatedFields.split(",");
//Setup data to return to form
var answer={};
//Do server side stuff
answer = this.getPairValuesDisplays(tableName, sysId, fieldNames);
//Encode data to send back to the form
return new JSON().encode(answer);
},
getPairValuesDisplays: function(table, sysId, fieldNames) {
var fieldsPairValues = {}; // New Structure to contain all our field values and displays
var gr = new GlideRecordSecure(table);
if (gr.get(sysId)) {
//Iterate through all our field names
for(var f in fieldNames) {
var fieldName = fieldNames[f];
var value = gr.getValue(fieldName);
if (value != null) { //Value is null if user has no read access
var fieldValueDisplay = {
value: gr.getValue(fieldName),
displayValue: gr.getDisplayValue(fieldName)
};
fieldsPairValues[fieldName] = fieldValueDisplay; //Add field data
}
}
}
return fieldsPairValues;
},
type: 'WhyStopAtOneAjax'
});
Like good programmers, we are going to test our code before even thinking about our Client Script.
This is key to not wasting hours mucking around with Client Scripts! Make sure your server code works first!
Below shows a quick little Test Harness I did to make sure the Display Values are being returned.
Use whatever tools you have at your disposal.
Let's focus on Department and Location fields, which will be our next requirement client side.
User Profile
Test Harness (Basic Example)
function positiveTestOne() {
var table = 'sys_user';
var sysid = gs.getUserID();
var fields = ['department','location'];
var ajaxTest = new WhyStopAtOneAjax();
var answer = ajaxTest.getPairValuesDisplays(table,sysid,fields);
if (answer.department.displayValue != "IT") {
throw('FAIL: Department NOT IT');
}
if (answer.location.displayValue != "Australia") {
throw('FAIL: Location NOT America');
}
}
try{
positiveTestOne();
} catch (e) {
gs.addErrorMessage(e);
} finally {
gs.addInfoMessage('Test Complete');
}
Client Side
A new requirement has emerged - retrieving Location and Company! We have already tested our code, so we are confident that this can work with Company instead of Department.
Old code - Get Location
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var ga = new GlideAjax('ShackleFreeAjax'); //Name of the Ajax Script Inclide
ga.addParam('sysparm_name','ajaxClientDataHandler'); //Method to call
//Add new parameters for our new GlideAjax Class
ga.addParam('sysparm_tablename','sys_user'); //Table name
ga.addParam('sysparm_sysid',newValue); //newValue
ga.addParam('sysparm_fieldname','location'); //Field name we want to retrieve
ga.getXML(userCallback);}
function userCallback(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
answer = answer.evalJSON();
setLocation(answer);
}
function setLocation(caller) { //returns only the values we need
if (caller) {
g_form.setValue(
'location',
caller.location.value, // use value
caller.location.displayValue //set value to avoid round-trip
);
}
}
New code - Get Location & Company
We need to change the code to
- Use new Script Include
- Pass multiple fields to server
- Set Company field
- Change function names to reflect code changes
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
jslog('hi');
var ga = new GlideAjax('WhyStopAtOneAjax'); //Name of the Ajax Script Inclide
ga.addParam('sysparm_name','ajaxClientDataHandler'); //Method to call
//Add new parameters for our new GlideAjax Class
ga.addParam('sysparm_tablename','sys_user'); //Table name
ga.addParam('sysparm_sysid',newValue); //newValue
ga.addParam('sysparm_fieldnames','location,company'); //Field name we want to retrieve
ga.getXML(userCallback);
}
function userCallback(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
answer = JSON.parse(answer);
setLocationAndCompany(answer);
}
function setLocationAndCompany(caller) { //returns only the values we need
if (caller) {
g_form.setValue('location', caller.location.value, caller.location.displayValue); //set value to avoid round-trip
g_form.setValue('company', caller.company.value, caller.company.displayValue); //set value to avoid round-trip
}
}
So there you have it!
You now have a GlideAjax Script include that can handle any table and fields!
- 1,487 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
