The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Shawn Dowler
Giga Guru

Click here for an updated version of the GlideAJAX Example Cheat Sheet

 

It can be hard to remember all of the Client and Server elements of a GlideAjax call. I created a simple example with color coding to help make sure I don't miss any of the details when I'm making a new call from scratch. I hope this helps. I attached a Word doc as well as the image and text below for convenience.

 

Note: Client callable must be checked in the Script Include for this to work

 

# Yellow:

This is the name of the class you create. This is usually the same as the name of the Script Include.

 

# Magenta:

This is the name of the function to use in the script include. You can have a single script include with multiple functions that accept and return different parameters. For example, you could create a single Script Include for getting data related to users and keep adding functions to it as needed.

 

# Green:

This is a parameter that is passed through the URL of the AJAX call. You can add more than one parameter. usually this is information you will use to make a GlideRecord call in the Script Include.

 

# Red:

This is the function that asynchronously waits for a response. Any code that you need to wait for a response needs to go in the function referred to in the getXML(). Code that doesn't need to wait goes directly after the getXML() call inside the main Client Script function and won't wait for a response before executing.

 

# Cyan:

These are the pieces of data you need from the Server. They are added to an object in the Script Include and passed back to the Client Script. You can do anything with these when they are returned. In this example they are used to set a value on the form.

 

Client Side (Client Script):

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

      if (isLoading || newValue == '') {

              return;

      }

     

      var ga = new GlideAjax('asu_GetLocationData');

      ga.addParam('sysparm_name', 'getCampus');

      ga.addParam('sysparm_buildingid', g_form.getValue("u_building"));

      ga.getXML(updateCampus);

}

     

function updateCampus(response) {

      var answer = response.responseXML.documentElement.getAttribute("answer");

      var clearvalue; // Stays Undefined

      if (answer) {

              var returneddata = answer.evalJSON(true);

              g_form.setValue("campus", returneddata.sys_id, returneddata.name);

      } else {

              g_form.setValue("campus", clearvalue);

      }

}

 

Server Side (Script Include):

var asu_GetLocationData = Class.create();

asu_GetLocationData.prototype = Object.extendsObject(AbstractAjaxProcessor, {

      getCampus: function () {

              var buildingid = this.getParameter('sysparm_buildingid');

              var loc = new GlideRecord('cmn_location');

              if (loc.get(buildingid)) {

                      var campus = new GlideRecord('cmn_location');

                      if (campus.get(loc.parent)){

                              var json = new JSON();

                              var results = {

                                      "sys_id": campus.getValue("sys_id"),

                                      "name": campus.getValue("name")

                              };

                              return json.encode(results);

                      }

              } else {    

                      return null;

              }            

      }

});

Comments
sndangibbard
Mega Guru

getXMLAnswer will return the answer element from the XML response removing the need for the very clunky line:



var answer = response.responseXML.documentElement.getAttribute("answer");



No idea why people don't use this method more!



https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GLAX-getXMLAnswer_F


Chuck Tomasi
ServiceNow Employee
ServiceNow Employee

Hi Shawn,



Very nicely done. I recall when I learning GlideAjax, the color coding really helped on the example I used. Thanks



I also recommend using JSON.stringify() instead json.encode() to do you encoding, and JSON.parse() instead of json.decode() as they is ECMAScript5 compliant and not a SN "version" of the same things. ES5 has been in place since Helsinki. If you're not there yet, here's another good reason to get up to date.


Shawn Dowler
Giga Guru

Thanks! I've been meaning to update my example. This was based on a cheat sheet I created a few years ago for myself, so some of the code is outdated. Maybe I could have an ES3 version and an ES5 version for users pre and post Helsinki. There are other things I'd like to clean up in the example, but I need the time to test it before making changes to the script.


heathers_
Tera Guru

Hi, we are upgrading from Helsinki to Jakarta and are running into an issue with the GlideAjax script include. Similar to your example, we are looking for the campus based off the building. The campus keeps clearing which leads me to believe that the sys_id is not pulling correct. I'm not sure what changed from Helsinki to Jakarta that would cause issues.

Catalog Client Script

function onChange(control, oldValue, newValue, isLoading) {
	
	if(isLoading)
		return;
	
	g_form.clearValue('room');
	
	var ga = new GlideAjax('DataHelperAJAX');
	ga.addParam('sysparm_name','singleSysid');
	ga.addParam('sysparm_table','alm_building');
	ga.addParam('building', g_form.getValue('building'));
	ga.getXML(populateCampus);
	
	function populateCampus(response) {
		var answer = response.responseXML.documentElement.getAttribute("answer");
		g_form.setValue('campus',answer);
	}
}

 

Script Include

var DataHelperAJAX = Class.create();
DataHelperAJAX.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	singleSysid: function(){
		var table = this.getParameter('table');
		var building = this.getParameter('building');
		
		var gr = new GlideRecord('alm_building');
		gr.addQuery('sys_id', building);
		gr.setLimit(1);
		gr.setWorkflow(false);
		gr.query();
		if(gr.next()){
			return gr.campus;
		} else {
			return '';
		}
	},
	
	type: 'DataHelperAJAX'
});
Mohammad Kadiw1
Giga Contributor

Hi heathers,

Looks like you need to change this line in your script include:

var table = this.getParameter('table');

This should be

var table = this.getParameter('sysparm_table');

That should fix it. Although it's best practice to pass the value and display name for a reference field as in the example above.

jhelebrant2112
Kilo Explorer

Thanks Shawn. This is really good info. 

edula
Kilo Contributor

HI ,

I have requirement like 

1. form table is different and section table is different.

2. I have section in that section i have around 20 feilds.

3. when I change any of the field in that section  pop should display with yes or no option.

4. current and previous value are also required.

5. when click on yes one specific catalog item should create with the old and new values updates in the section.

6. Catalog Item  request item has to get created  for validating old and new values. and workflow should trigger for approval.

7. After approving new value should update in the fields. 

Francis Cavaciu
Kilo Guru

I might be wrong but I think it's because getXMLAnswer will cause the client to hang while it waits for the Answer, which could defeat the point of using GlideAjax in this instance.

Oliver13
Kilo Guru

Hi Shawn,

Thank you for sharing. I followed your instructions, but it's not working for me. 

 

My Server side script includes:

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

    getFieldValue: function() {

        var subjectPerson = this.getParameter('subject_person');
		
		var hrProfile = new GlideRecord('sn_hr_core_profile');
		hrProfile.addQuery('user', subjectPerson);
		hrProfile.query();
		
		if(hrProfile.next()) {
			
			var json = new JSON();
			var results = {
				
				"new_line_manager": hrProfile.getDisplayValue('user.manager'),
				"cost_center_home": hrProfile.getDisplayValue('u_cost_center'),
				"cost_center_host": hrProfile.getDisplayValue('u_cost_center_host'),
				"department": hrProfile.getDisplayValue('user.department'),
				"gbu_home": hrProfile.getDisplayValue('u_global_business_unit'),
				"gbu_host": hrProfile.getDisplayValue('u_global_business_unit_host'),
				"bu_home": hrProfile.getDisplayValue('u_business_unit'),
				"bu_host": hrProfile.getDisplayValue('u_business_unit_host'),
				"sub_bu_home": hrProfile.getDisplayValue('u_sub_business_unit'),
				"sub_bu_host": hrProfile.getDisplayValue('u_sub_business_unit_host'),
				"job_family_home": hrProfile.getDisplayValue('u_job_family'),
				"job_family_host": hrProfile.getDisplayValue('u_job_family_host'),
				"sub_job_family_home": hrProfile.getDisplayValue('u_sub_job_family'),
				"sub_job_family_host": hrProfile.getDisplayValue('u_sub_job_family_host'),
				"discipline_home": hrProfile.getDisplayValue('u_discipline'),
				"discipline_host": hrProfile.getDisplayValue('u_discipline_host'),
				"group_job_name": hrProfile.getDisplayValue('u_group_job_name'),
				"group_job_host": hrProfile.getDisplayValue('u_group_job_name_host'),
				"legal_entity_home": hrProfile.getDisplayValue('u_legal_employer'),
				"legal_entity_host": hrProfile.getDisplayValue('u_legal_employer_host')
				
			};
			
			return json.encode(results);
				
		}

    },

    type: 'DVTHRProfileAjax'
});

 

My onChange client script:

find_real_file.png

 

 

 

The issue is that answer is returned as null on the client side. 

Could you help me check it?

 

Thank you.

 

Allen Andreas
Tera Patron
Tera Patron

Hello,

Please use the forum tools as appropriate to organize your code. If you look at your post now, it's all slammed in to a wall of text and completely unreadable.

find_real_file.png

Please mark reply as Helpful, if applicable. Thanks!

Oliver13
Kilo Guru

Hello Allen,

I did. 🙂 thank you.

Mohammad K
Tera Expert

Hello Oliver,

it looks like there are a few changes you need to make.

First of all, in your client script:

the function updateField(response) needs to be outside the onChange function. So you need a close bracket "}" on line 13 and remove the one on your last line.

I also recommend using getXMLAnswer() instead of getXML(). It saves you from having to parse the answer out in the callback function. See below:

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }
	
	var ga = new GlideAjax('DVTHRProfileAjax');
	ga.addParam('sysparm_name','getFieldValue');
	ga.addParam('subject_person',g_form.getValue('subject_person'));
	//ga.getXML(updateField);
	ga.getXMLAnswer(updateField);
	
}

function updateField(response) {
	//var answer = response.responseXML.documentElement.getAttribute('answer');
	g_form.addInfoMessage(response);
}

 

The second issue in the Script include. As Chuck Tomasi had suggested, you really should be using JSON.stringify() and JSON.parse() instead of encode() and decode(). In fact, I believe that has been deprecated now which is why your Script include is not completing. You must remove the line

var json = new JSON();

 

There are two options to use JSON.stringify. You can keep your results object as defined and then use JSON.stringify(results) or you can just do it in one operation and return JSON.stringify({yourObjectData}).

 

Option1:

var DVTHRProfileAjax  = Class.create();
DVTHRProfileAjax .prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
	
	getFieldValue: function() {
		var subjectPerson = this.getParameter('subject_person');
		
		var hrProfile = new GlideRecord('sn_hr_core_profile');
		hrProfile.addQuery('user', subjectPerson);
		hrProfile.query();
		
		if (hrProfile.next()) {
			//var json = new JSON();
			var results = {
				"new_line_manager": hrProfile.getDisplayValue('user.manager'),
				"cost_center_home": hrProfile.getDisplayValue('u_cost_center'),
				"cost_center_host": hrProfile.getDisplayValue('u_cost_center_host'),
				"department": hrProfile.getDisplayValue('user.department'),
				"gbu_home": hrProfile.getDisplayValue('u_global_business_unit'),
				"gbu_host": hrProfile.getDisplayValue('u_global_business_unit_host'),
				"bu_home": hrProfile.getDisplayValue('u_business_unit'),
				"bu_host": hrProfile.getDisplayValue('u_business_unit_host'),
				"sub_bu_home": hrProfile.getDisplayValue('u_sub_business_unit'),
				"sub_bu_host": hrProfile.getDisplayValue('u_sub_business_unit_host'),
				"job_family_home": hrProfile.getDisplayValue('u_job_family'),
				"job_family_host": hrProfile.getDisplayValue('u_job_family_host'),
				"sub_job_family_home": hrProfile.getDisplayValue('u_sub_job_family'),
				"sub_job_family_host": hrProfile.getDisplayValue('u_sub_job_family_host'),
				"discipline_home": hrProfile.getDisplayValue('u_discipline'),
				"discipline_host": hrProfile.getDisplayValue('u_discipline_host'),
				"group_job_name": hrProfile.getDisplayValue('u_group_job_name'),
				"group_job_host": hrProfile.getDisplayValue('u_group_job_name_host'),
				"legal_entity_home": hrProfile.getDisplayValue('u_legal_employer'),
				"legal_entity_host": hrProfile.getDisplayValue('u_legal_employer_host')
			};
			//return json.encode(results);	
			return JSON.stringify(results);
		}
	},

    type: 'DVTHRProfileAjax '
});

Option2:

if (hrProfile.next()) {
  return JSON.stringify({
    "new_line_manager": hrProfile.getDisplayValue('user.manager'),
		"cost_center_home": hrProfile.getDisplayValue('u_cost_center'),
		"cost_center_host": hrProfile.getDisplayValue('u_cost_center_host'),
		"department": hrProfile.getDisplayValue('user.department'),
		"gbu_home": hrProfile.getDisplayValue('u_global_business_unit'),
		"gbu_host": hrProfile.getDisplayValue('u_global_business_unit_host'),
		"bu_home": hrProfile.getDisplayValue('u_business_unit'),
		"bu_host": hrProfile.getDisplayValue('u_business_unit_host'),
		"sub_bu_home": hrProfile.getDisplayValue('u_sub_business_unit'),
		"sub_bu_host": hrProfile.getDisplayValue('u_sub_business_unit_host'),
		"job_family_home": hrProfile.getDisplayValue('u_job_family'),
		"job_family_host": hrProfile.getDisplayValue('u_job_family_host'),
		"sub_job_family_home": hrProfile.getDisplayValue('u_sub_job_family'),
		"sub_job_family_host": hrProfile.getDisplayValue('u_sub_job_family_host'),
		"discipline_home": hrProfile.getDisplayValue('u_discipline'),
		"discipline_host": hrProfile.getDisplayValue('u_discipline_host'),
		"group_job_name": hrProfile.getDisplayValue('u_group_job_name'),
		"group_job_host": hrProfile.getDisplayValue('u_group_job_name_host'),
		"legal_entity_home": hrProfile.getDisplayValue('u_legal_employer'),
		"legal_entity_host": hrProfile.getDisplayValue('u_legal_employer_host')
	});
}
Francis Cavaciu
Kilo Guru

Hi Mohammad,
Quick note, getXMLAnswer will cause the browser to hang the same way that getXMLWait will, therefore it is not recommended unless you specifically need the browser to wait until the ajax response has been received before continuing to process your client side code.

Cheers

Francis C.

Shawn Dowler
Giga Guru

I finally created an updated version of this article trying to incorporate the comments here.

GlideAjax Example Cheat Sheet (UPDATED)

Shawn Dowler
Giga Guru

@GADE RAJU The screenshots don't match the text of the scripts pasted in the comment. I looked a the pasted text and didn't see anything that stuck out as wrong on first glance. I just wanted to make sure which scripts you are struggling with. Is it both?

 

I see you have an alert() in there. Does the alert() show any data? Have you tried debugging the Script Include? Is the sys_id making it to the server side? Is the Glide Record lookup returning the user data for that sys_id? You need to track down where the data isn't making it to the next step.

Karimisetti
Giga Explorer

Client scripts:


function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}

//Type appropriate comment here, and begin script below
var gal = new GlideAjax('CallerEmail');
gal.addParam("sysparm_name", "getDate");
gal.addParam("sysparm_userselected", g_form.getValue('u_caller_id'));
gal.getXMLAnswer(setDetails);

function setDetails(response) {
var userobj = JSON.parse(response);
g_form.setValue('u_email', userobj.email);
}

}

 

Script Include;

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

getDate: function() {
var user = this.getParameter('sysparm_userselected');

var usr = new GlideRecord('sys_user');
usr.addQuery('sys_id', user);
usr.query();
if (usr.get(user)) {
var obj = {};
obj.email = usr.getDisplayValue('email');
}
return JSON.stringify(obj);
},

type: 'CallerEmail'
});



 

Shrngika
Tera Expert

code is well explained but what is use case can anyone explain this code for what?

Shrngika
Tera Expert

Hello @Shawn Dowler  can you explain what the code is doing.

I mean what is the use case.

dev115415
Tera Expert

Hello

I want to  make an API call to an external application from Script Include. How to do this? 

Version history
Last update:
‎10-27-2017 11:23 AM
Updated by: