Client Script - Why GlideAjax(with getXMLAnswer) ?

The table is a good visualization of Simplicity versus Efficiency.

APISimplicityEfficiencyDescription
GlideRecord getReference1st5th- 1 line of code
- Poor UX (blocks browser)
- Returns entire record 
GlideRecord2nd4rd- ~ 5 lines of code
- Poor UX (blocks browser)
- Returns entire record
GlideRecord getReference
(with callback)
3rd3rd- 5-10 lines of code (with callback)
- Best UX (does not block browser)
- Returns entire record
GlideRecord
(with callback)
4th2nd- ~ 10 lines of code (with callback)
- Best UX (does not block browser)
- Returns entire record
GlideAjax5th1st- ~20 lines of code (Client Script + Script Include)
- Best UX (does not block browser)
- Returns only the data you need


Note: Actually I would change "GlideAjax" into "GlideAjax (with getXMLAnswer)". GlideAjax with getXML still would return a whole document. While GlideAjax with getXMLAnswer would only return the exact answer you need. Read about this in one of my previous articles

GlideAjax examples

1) We would like to retrieve the Phone number of a Caller selected. Phone number should be written to a custom Phone number field on the Incident form (u_phone).

Script Include

Name: getUserPropertiesAjax
Client callable: true
Script:

var getUserPropertiesAjax = Class.create();
getUserPropertiesAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	get_phone : function() {
		var grUser = new GlideRecord('sys_user');

		if(grUser.get(this.getParameter('sysparm_user'))) {
			return grUser.getValue('phone');
		}
	},
	
    type: 'getUserPropertiesAjax'
	
});

Client Script

Table: Incident
Type: onChange
Field name: Caller
Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

	if(isLoading) {
		return;
	}

	if(newValue === '') {
		g_form.clearValue('u_phone');
	}

	var gaPhone = new GlideAjax('getUserPropertiesAjax');
	gaPhone.addParam('sysparm_name', 'get_phone');
	gaPhone.addParam('sysparm_user', newValue);
	gaPhone.getXMLAnswer(_handleResponse);

	function _handleResponse(response) {
		var answer = response;
		
		g_form.setValue('u_phone', answer);
	}

}

2) We would like to retrieve the Location of a Caller selected. Location should be written to the out-of-the-box Location field on the Incident form (location).

Script Include

We'll just add a function "get_location" to the Script Include created earlier.

Script:

var getUserPropertiesAJAX = Class.create();
getUserPropertiesAJAX.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	get_phone : function() {
		var grUser = new GlideRecord('sys_user');

		if(grUser.get(this.getParameter('sysparm_user'))) {
			return grUser.getValue('phone');
		}
	},
	
	get_location : function() {
		var grUser = new GlideRecord('sys_user');

		if(grUser.get(this.getParameter('sysparm_user'))) {
			var answer = {};
			answer.value = grUser.getValue('location');
			answer.displayValue = grUser.getDisplayValue('location');
			return JSON.stringify(answer);
		}
	},
	
    type: 'getUserPropertiesAJAX'
	
});

Note: Instead of just returning "return grUser.getValue('location')", we are actually returning the getValue and the getDisplayValue. This is because g_form.setValue(), for a Reference field expects the value AND the display value. If only returning the value (the sys_id), an additional Server call will be performed (and the efficiency reason for why performing GlideAjax would then actually be lost).

Client Script

Table: Incident
Type: onChange
Field name: Caller
Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

	if(isLoading) {
		return;
	}

	if(newValue === '') {
		g_form.clearValue('location');
	}

	var gaLocation = new GlideAjax('getUserPropertiesAJAX');
	gaLocation.addParam('sysparm_name', 'get_location');
	gaLocation.addParam('sysparm_user', newValue);
	gaLocation.getXMLAnswer(_handleResponse);

	function _handleResponse(response) {
		var answer = JSON.parse(response);
		g_form.setValue('location', answer.value, answer.displayValue);
	}

}

Note: When using the Script Editor, notice the information on g_form.setValue:

find_real_file.png

Making life easier

So is there anything we can do about the downside of going for the top-ranked efficiency, which actually brings bottom-ranked simplicity?

1) Set up example (Catalog) Client Scripts
Client Scripts which you could simply "Insert and Stay", and modify. No need to write all the code out again.

2) Syntax Editor Macros
Write example GlideAjax call ones and save it in a Syntax Editor Macro. Syntax Editor Macros can easily be called within a Script field. 

Dynamic GlideAjax

You might already notice, the functions in the Script Include can be used over and over, nice. Though for example, if you would now like to get your hands on the Email value of the User record, you would have to add a function again.
This can be done easier ðŸ™‚


Comments

Popular posts from this blog

Background Scripts

Glide Record Cheat Sheet

Setup OAuth2 authentication for RESTMessageV2 integrations