CatalogUtil – A GlideAjax Multi-tool

Customers of mine who use the service catalog tend to really use the service catalog. Many of them have big ambitions when it comes to what their catalog items, order guides, and record producers can do. This often results in leveraging GlideAjax in catalog client script, which means writing a corresponding script include to do the dirty work. I find that many of these script includes are effectively doing the same thing – Get a value, get a reference and its display value, etc.

Instead of writing a new script include or adding methods to an existing script include, I typically load a script include and leverage it over and over. This is something I put together years ago and haven’t modified much since.

CatalogUtil

var CatalogUtil = Class.create();
CatalogUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	getValue: function(table, field, uid) {

		var tableGR = new GlideRecord(table);
		tableGR.addQuery('sys_id', uid);
		tableGR.query();

		if (tableGR.next()) {
			return tableGR[field];
		}
	},

	getValueAjax: function() {
		var table = this.getParameter('table'),
			field = this.getParameter('field'),
			uid = this.getParameter('uid');

		return this.getValue(table, field, uid);
	},

	getReferenceValue: function(table, field, uid) {

		var tableGR = new GlideRecord(table),
			retObj = {};
		tableGR.addQuery('sys_id', uid);
		tableGR.query();

		if (tableGR.next()) {
			retObj.label = tableGR[field].getDisplayValue();
			retObj.value = tableGR[field] + '';
			return retObj;
		}
	},

	getReferenceValueAjax: function() {
		var table = this.getParameter('table'),
			field = this.getParameter('field'),
			uid = this.getParameter('uid');

		return JSON.stringify(this.getReferenceValue(table, field, uid));
	},
	
	getProperty: function() {
		var prop = this.getParameter('sysparm_property');
		return gs.getProperty(prop);
	},
	type: 'CatalogUtil'
});

If you use this, be sure to check the Client Callable checkbox. I have set this to be accessible to all application scopes, as well, but you could do with that whatever fits your situation.

I should probably add JSDocs or something to this, but if I were to comment my code, I’d be an honest developer. And I can’t be doing that.

Client Script Examples

There’s no reason why the use of this should be limited to the service catalog/portal… this could be leveraged anywhere that client-side scripting is used. Here are some catalog client script examples of this in action for each method:

getValueAjax

This simply pulls the email address of the user in the requestedFor variable and sets the emailAddress variable with that value.

function onLoad() {
	var reqFor = g_form.getValue('requestedFor');
	if (reqFor != '') {
		var getEmail = new GlideAjax('CatalogUtil');
		getEmail.addParam('sysparm_name', 'getValueAjax');
		getEmail.addParam('table', 'sys_user');
		getEmail.addParam('uid', reqFor);
		getEmail.addParam('field', 'email');
		getEmail.getXMLAnswer(setEmail);
	}
	
	function setEmail(answer) {
		g_form.setValue('emailAddress', answer);
	}
}

getReferenceValueAjax

This is similar to getValueAjax, but returns the display value for the reference field, as well. This ends up saving the user and system an extra AJAX call to get the display value when a reference field is set.

function onChange(control, oldValue, newValue, isLoading) {
	if (isLoading){
		return;
	} 
	
	if (newValue == '') {
		g_form.setValue('department', '');
		return;
	} else {
		var dept = new GlideAjax('CatalogUtil');
		dept.addParam('sysparm_name', 'getReferenceValueAjax');
		dept.addParam('table', 'sys_user');
		dept.addParam('field', 'department');
		dept.addParam('uid', newValue);
		dept.getXMLAnswer(setDepartment);
	}
	
	function setDepartment(answer) {
		var answerObj = JSON.parse(answer);
		g_form.setValue('department', answerObj.value, answerObj.label);
	}
}

getProperty

This is something I wrote about previously, but it’s really where I keep this method for regular use. It takes a property name and returns the value. Easy enough!

function onLoad() {
	var catItemID = g_form.getUniqueValue();
	var propAjax = new GlideAjax('CatalogUtil');
	propAjax.addParam('sysparm_name', 'getProperty');
	propAjax.addParam('sysparm_property', 'cat_item_ids_without_automation'); //comma-separated string of sys_ids
	propAjax.getXMLAnswer(processResponse);

	function processResponse(response) {
		if (response.toString().indexOf(catItemID) > -1) {
			g_form.setMandatory('group_auto', false);
			g_form.setValue('group_auto', '');
			g_form.setDisplay('group_auto', false);
		} else {
			g_form.setDisplay('group_auto', true);
			g_form.setMandatory('group_auto', true);
		}
	}
}

You may have noticed that I have two versions of some methods (getValue and getValueAjax, for example). The reason I do this is so that I can leverage CatalogUtil in a server-side script, too. (Once in a while, I have a really good idea.) The getProperty method doesn’t need it since it’s only AJAX (the server-side version just uses gs.getProperty() directly).

This simple utility script has become indispensable for me over the years. It hasn’t completely eliminated the need for custom client-callable script includes, but it does quite a bit for me. Enjoy!

Leave a Reply