Announcing the Global SNUG Board of Directors. Learn more here
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.
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
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 -
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.
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');
}
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.
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
);
}
}
We need to change the code to
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!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.