We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

paulmorris
Giga Sage

How to Write Smart GlideAjax Quickly

Contents

Part 1 - The Approach

Part 2 - Reusability

Part 3 - Extending Functionality

Part 4 - Implementing GlideAjax in 1 LOC

Part 5 - Auto populating Fields 

Auto populating fields 

I've been using my own SmartAjax scripts on almost every implementation I work on, as it saves so much time and makes retrieving server-side data so simple. I'm always trying to think of ways to improve my existing code, so I decided to refine SmartAjax even further. 

The Common Use Case

The most common form of GlideAjax code usually goes something like this:

  • For a particular record that is referenced on my form
  • When that field changes value 
  • Get some fields from that record
  • Populate my form based on that record

I still found myself re-writing the same code in my callback function, which would usually go something like this:

var caller = s_ajax.getReference('caller_id',callback,['location','department']);

function callback(caller) {

	if (caller.hasOwnProperty('department')) {
		g_form.setValue('my_department_field', caller.department, caller.getDisplayValue('department'));
	} else {
		// If user has no department, clear value
		g_form.clearValue('my_department_field');
	}

	if (caller.hasOwnProperty('location')) {
		g_form.setValue('my_location_field', caller.location, caller.getDisplayValue('location'));
	} else {
		// If user has no department, clear value
		g_form.clearValue('my_location_field');
	}

}

I wanted to codify this pattern while keeping to 1 LOC, so I created the Class SmartAjaxFieldMapper.

SmartAjaxFieldMapper

The syntax is as follows:

new SmartAjaxFieldMapper('caller_id')
	.addFieldMapping('my_department_field','department')
	.addFieldMapping('my_location_field','location')
	.getReference();

The API will then automatically populate the fields based on reference values.

SmartAjaxFieldMapper is just a deceivingly simple wrapper around s_ajax that simplifies the callback.
It has the following class variables

var referenceField;
var fieldMappings = {};
var fieldsToGet = [];


addFieldMapping()
functions return this, allowing you to stack mappings:

  addFieldMapping: function(fieldName, refField) {
	if (g_form.getElement(fieldName)) {
		fieldMappings[fieldName] = refField;
		fieldsToGet.push(refField); // Used for s_ajax
	} else {
		log(fieldName + ' is an invalid field name and will not be mapped');
	}
    return this;
},


getReference() 
function just uses a premade callback function that codifies the common use case pattern:

function mapFields(response) {

    for (var fieldName in fieldMappings) {
        var refField = fieldMappings[fieldName];

        if (response.hasOwnProperty(refField)) {
            g_form.setValue(fieldName, response[refField], response.getDisplayValue(refField));
        } else {
            g_form.clearValue(fieldName);
        }

    }

}


You can even pass is your own callback function if you would rather do something more complex:

var complexFunction = function(caller) {
   alert(caller.getDisplayValue('department'));
}

new SmartAjaxFieldMapper('caller_id')
	.addFieldMapping('my_department_field','department')
	.addFieldMapping('my_location_field','location')
	.getReference(complexFunction);

Another example with the console:

var helloWorld = function(caller_id) {
	alert(caller_id.email);
}

new SmartAjaxFieldMapper('caller_id')
.flashFieldsOnChange()
.addFieldMapping('short_description','user_name')
.addFieldMapping('location','location')
.addFieldMapping('invalid_field_name','locations')
.addField('email')
.getReference(helloWorld);

find_real_file.png

find_real_file.png
This new API is available via the existing SmartAjax Share App.

It can also be used in Service Portal, just like SmartAjax

new SmartAjaxFieldMapper('refvar',g_form)
	.addFieldMapping('var1','department')
	.addFieldMapping('var2','location')
	.getReference();

If you liked this blog, please check out and bookmark some of my others here 🙂