
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.
DIFFICULTY LEVEL: INTERMEDIATE
Assumes having taken the class SSNF and has good intermediate level of knowledge and/or familiarity with Scripting in ServiceNow.
Here is a neat trick I thought I would pass on. How to push an object such as an object array to the server using Ajax and JSON. With this example I will also be demonstrating usage of the Ajax pattern I described in my AJAX logging article.
Lab 1.1: Using JSON and Ajax to Transmit a Complex Object to the Server
So let's do this right, and follow the development process. We will need a requirement statement, a design (we can skip the analysis for such a short demonstration), and development. Then finally test.
Requirements
- Create a button on the Incident form that transmits the incident's watch list emails to the system log.
Design
- New non-client enabled Script Include Function Library.
- Name: ArrayHandlingUtils.
- Client: Not checked.
- Method: getEmailsFromSysIDs. Will take a list of user sys_ids and return a list of their respective names and emails. Make sure to take into account the possibility of no email being present for a given user. This must be generic.
- New client enabled Script Include.
- Name: AjaxUtilsServer.
- Client: Checked.
- Method: pushListToSysLog. Will take an Ajax parameter that is a JSON encoded object that contains a "location" field that represents the calling UI Action/UI Policy/Client Script, and an array of watch list sys_ids garnered from any form, and then push this list to the System Log. Notice this MUST be generic.
- New UI Script to contain generic functions for reuse.
- Name: AjaxUtilsClient.
- Method: sendListToSysLog. Will take a location parameter, and a comma delimited list of sys_ids (this can also be an array of sys_ids). The location parameter will contain a string representing name of the calling control (UI Action/UI Policy/Client Script). The list of sys_ids can be any list of comma delimited sys_ids (or an array of sys_ids). The comma delimited list of sys_ids will be converted into an array. The location, and array will be placed into a listInfo object and using JSON and Ajax will be sent to the AjaxUtilsServer.pushListToSysLog method.
- New UI Action associated to the Incident form.
- Name: Transfer Watchlist.
- Table: Incident.
- Client: Checked.
- Method: sendWatchList. his will pull the watch list from the Incident form and call the UI Script method AjaxUtilsClient.sendListToSysLog.
- Unit Test
- Navigate to Incidents -> Open. The list view of open Incidents will be displayed.
- Open one of the Incidents. You should have a new button labeled: Transmit Watchlist.
- Make sure there are four or five people on the watchlist. Add some if you have to.
- Click on the Transmit Watchlist button.
- Navigate to System Log. Order by Created date descending.
- Expected Result: A list of names and emails matching the watchlist should be present as a log entry.
Development
So we have a couple of ways to do this: 1) Top-down, or 2) Bottom-up. Either way will work. I will use top-down for this lab.
- Navigate to Incidents -> Open. A list of open incidents will appear.
- Click on any Incident number to edit that incident. The incident form will appear.
- Right-click on the form header to bring up the form context menu.
- Pick Configure -> UI Actions from the menu. The Incident UI Action list view will be displayed.
- Click on the New button. The New UI Action form will be displayed.
- Fill out the form with the following:
- Name: Transfer Watchlist
- Table: Incident
- Active: checked
- Show Insert: checked
- Show Update: checked
- Client: checked
- Form Button: checked
- Comments (optional): Mini-Lab: Using Ajax and JSON to Send Objects to the Server
- OnClick: sendWatchList()
- Code:
function sendWatchList() {
sendListToSysLog(g_form.getValue('watch_list'), 'UIA:Transfer Watch List');
}
Your UI Action should look like this:
7. Click the Submit button to save your work. [Design element #4 is complete]
8. Navigate to System UI -> UI Scripts. The UI Scripts list view will be displayed.
9. Click on the New button. The New UI Script form will be displayed.
10. Fill out the form with the following:
- Name: AjaxUtilsClient
- Global: checked
- Active: checked
- Description: Transmits a list of sys_ids to the server to be pushed to the System Log.
- Code:
// Transmits a list of sys_ids to the server to be pushed to the System Log.
function sendListToSysLog(list, location) {
// build the object to be transmitted to the server-side.
var infoOnList = {};
infoOnList.location = location;
// we are turning this into an array just for demonstration purposes
// it really isn't necessary to do this.
infoOnList.list = list.split(','); // turn it into an array
// set up the Ajax call to the server.
var systemLogger = new GlideAjax('AjaxUtilsServer');
// the first parameter is always the name of the function we are calling
systemLogger.addParam('sysparm_name','pushListToSysLog');
// here is the secret sauce!
// JSON.stringify will package up your object and allow it to be
// transmitted to the server where it will be re-constituted into the same object!
systemLogger.addParam('sysparm_listInfo', JSON.stringify(infoOnList));
// this is one way of creating an Asynch call with a do-nothing callback.
systemLogger.getXML(function(result){ }); // no callback action
}
Your UI Script should look like this:
11. Click the Submit button to save your work. [Design element #3 is complete]
12. Navigate to System Definition -> Script Includes. The list view of Script Includes will be displayed.
13. Click the New button. The New Script Include form will be displayed.
14. Fill out the form with the following:
- Name: AjaxUtilsServer
- Client callable: checked. When you check this box the code template will switch to extending the AbstractAjaxProcessor.
- Accessible from: all application scopes
- Active: checked
- Description: Ajax utility library
- Code:
var AjaxUtilsServer = Class.create();
AjaxUtilsServer.prototype = Object.extendsObject(AbstractAjaxProcessor, {
// method for decoding the passed JSON object and writing it to the system log
pushListToSysLog: function() {
// this is how you re-constitute a JSON encoded object.
// This will rebuild our listInfo object from the front-end (browser)
var listInfo = JSON.parse(this.getParameter('sysparm_listInfo'));
// use a message variable to package up our log message.
var message = '---> \n';
message += 'Location: ' + listInfo.location + '\n';
// call our function to go retrieve an object list of names
// and emails for the given list of sys_ids
var userList = ArrayHandlingUtils.getEmailsFromSysIDs(listInfo.list);
// loop through our object array and build the log entry
for (var i=0; i < userList.length; i++) {
message += 'EMail[' + i + ']: '
+ userList[i].name + ' - '
+ userList[i].email + '\n';
}
// Write everything to the system log!
gs.info('---> [{1}] {0}', [message, 'SI:AjaxUtilsServer.pushListToSysLog']);
},
type: 'AjaxUtilsServer'
});
Your Script Include should look like this:
15. Click the Submit button to save your work. The list view of Script Includes will be re-displayed. [Design element #2 is complete]
16. A pop-up will appear asking for a user role for access control. Since this is for Incidents select: itil and click the OK button
17. Click on the New button again. The New Script include form will be displayed.
18. Fill out the form with the following:
- Name: ArrayHandlingUtils
- Client callable: un-checked.
- Accessible from: all application scopes
- Active: checked
- Description: Function library containing utilities for generating arrays
- Code:
var ArrayHandlingUtils = Class.create();
ArrayHandlingUtils.getEmailsFromSysIDs = function(sysIDList) {
// retrieve all user records in the list of sys_ids
var userRecords = new GlideRecord('sys_user');
userRecords.addQuery('sys_id', 'IN', sysIDList);
userRecords.query();
var userList = [];
// loop through all the user records and break out the name
// and email into the user object.
while (userRecords.next()) {
var user = {}; // always initialize your object before using!
user.name = userRecords.name + '';
var email = userRecords.email + '';
user.email = JSUtil.notNil(email) ? email : 'no email found';
// place the user object into the object array
userList.push(user);
}
return userList;
};
Your utility Script Include should look like this:
19. Click the Submit button to save your work. [Design element #1 is complete]
Unit Test
Our unit test should be pretty much what we had in our design [element #5]:
- Navigate to Incident -> Open. The list view of open Incidents will be displayed.
- Open one of the Incidents. You should have a new button labeled: Transfer Watchlist.
- Make sure there are four or five people on the watchlist. Add some if you have to.
- Click on the Transfer Watchlist button. Nothing seems to happen, but a log entry should be written. I guess we could always go back and put in a g_form message that things have finished, but this is supposed be a lab that emulates something you might do for real!
- Navigate to System Log -> All. Order by Created date descending.
- Expected Result: A list of names and emails matching the watchlist should be present as a log entry.
Note: Since you are an admin on your instance you will see this. You could test further by impersonating an ITIL and non-ITIL user to make sure the Ajax Script Include cannot be accessed (just a security thing to check right?).
And there you have it! We created the code based on the Ajax pattern to organize everything nicely. The code is generic enough that the UI Script through the Script Include function can be reused and expanded at a later time (extensibility). Nothing present is hard-coded, but rather data driven. Finally, we demonstrated the method for JSON encoding an object on the front-end (browser), transmitting that object via Ajax to the server-side, and JSON decoding the object for use.
Best Practices employed:
- Maintainability
- Reusability
- Extensibility
- Efficient code
For more information on JavaScript JSON stringify and parse.
Enjoy!
Steven Bell.
If you find this article helps you, don't forget to log in and mark it as "Helpful"!
Originally published on: 01-26-2016 07:29 AM
I updated the code and brought the article into alignment with my new formatting standard.
- 3,451 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.