Script examples

Now that we have seen some more advanced ways of using client-side script, let's look at some examples of how to use these newly learned techniques.

Let's first look at UI actions. We may want to use a UI action to progress states in a change record, but we want to make sure certain fields are filled in before we progress on to other states. We can use client- and server-side code to achieve this. First we use the client-side code to validate the form, and then the server-side code to perform changes to the record.

We can have a look at how this would work:

function validateForm() {
g_form.setMandatory('justification', true);

//Call the UI Action to run the server side script
gsftSubmit(null, g_form.getFormElement(), 'authorize');
g_form.setMandatory('justification', false);
}

if(typeof window == 'undefined')
setToAuthorize();

function setToAuthorize() {
current.state = -3; //Authorize state
current.update();

}

In the example, on the client-side script, we are setting the field we want populated to Mandatory in the script to ensure that it is populated before the form is submitted. This is a good way of notifying the user of the additional field to fill in, as it uses the ServiceNow Mandatory functionality, rather than popups appearing to the user. You will notice that after the submission, we stop the field being Mandatory. This is so that if the user wants to simply save the form or change different field values, they are not stopped by the justification field still being Mandatory.

For submitting the form, we use gsftSubmit and the action name of our UI action, which, in this example, is authorize. This allows the server-side script to run our server function, setToAuthorize. As the state field uses numbers as its values, we set the field to -3, and, as in the example, it is good practice to add comments to let other developers know what the value equates to; and it can be a good reminder for yourself.

We can take a look at what this UI action would look like in Figure 4.2:

Figure 4.2: Authorizing UI action with client- and server-side script

This method of using client script to validate and server script to perform actions is very useful and works very nicely for UI actions.

Now let's take a look at an AJAX call example. For this example, we are going to look at a catalog item with dependencies on the variables in the catalog item. Sometimes users may have certain access that needs to be revoked, perhaps when they leave the company. When we select the user, we want to ensure that they have some kind of access; otherwise, there will be nothing for them to pick in the remaining fields, resulting in a poor user experience.

Let us take a look at the client-side script we would put into a catalog client script:

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) {
return;
}

//Clear the Access field when the user changes to ensure a valid selection is made.
g_form.setValue('variables.access', '');

if (newValue == '') {
return;
}

//Ensure a selected user has some active access else clear field
var ga = new GlideAjax('accessCheck');
ga.addParam('sysparm_name','userHasAccess');
ga.addParam('sysparm_user', newValue);
ga.getXML(AJAXParse);

}

function AJAXParse(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer == 'false') {
g_form.addErrorMessage('User has no access to remove.');
g_form.setValue('variables.user', '');
}
}

This would be put inside a catalog client script as an onChange script, and therefore dictates our function name. When we use catalog items and variables, we have to prefix our variable names with variables and then the variable name to use g_form methods. In the example, we are using a user and access variable, and as you can see, we clear the access variable when the user changes so that we don't end up with a mismatch of data on the screen where a user picks some access and then back fills the user.

Before we initiate the AJAX call, we check that the new value of the user field is not blank. If it is, there is no use making a round-trip to the server, so we use return, essentially exiting the script. If the value is not blank, then we use an AJAX call, calling our script include and sending a user parameter containing the new value in the user field.

When a response comes back from the server, if the result is that the user has no access, then we can assume there will be no access to select and remove for the user. Therefore there would be no selections to pick in the access variable. Rather than give the user nothing to select, we can clear the user field and let the user know the user they selected has no access to remove.

Now that we have taken a look at the client side of this example, let's have a look at the server-side code. Remember that the script include name and function need to match up with the client code making the AJAX call:

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


/**
* Ajax Call - Returns whether a user has an active access record
*/
userHasAccess: function userHasAccess() {

var uAccess = new GlideRecord('u_access');
uAccess.addQuery('u_user', this.getParameter('sysparm_user'));
uAccess.query();
if (uAccess.next()) {
return true;
}
return false;
}

});

In the server script, we are using a GlideRecord to check a custom access table, hence the u_ prefix using the sysparm_user parameter we passed to filter the result down to only records containing that user. If we find a record of access, we return true back to the client and false if no record can be found.

By returning false back to the client-side script, we clear the user variable on the form and show an error message so that the logged-in user knows that the user they selected has no access. If we assume a suitable reference qualifier has been set up, this would stop the logged-in user selecting the access variable after selecting a user and finding no records to select.

Since AJAX calls are so widely used, let's take a look at another example. In this example, we will notify a user on the incident form whether the change they have selected related to the incident that still has open tasks.

This time, we'll use a client script to make the AJAX call. We need it to run when the change request field changes on the incident form, so we'll use an onChange script. Let's have a look at how this client script code will look:

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

//Check whether change request has open tasks
var ga = new GlideAjax('changeScripts');
ga.addParam('sysparm_name','changeHasOpenTasks');
ga.addParam('sysparm_change', newValue);
ga.getXML(AJAXCall);

}

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

if (answer == 'true') {
g_form.showFieldMsg('rfc', 'Change has open tasks', 'error');
} else {
g_form.showFieldMsg('rfc', 'Change has no open tasks', 'info');
}
}

In this example, we see an AJAX call again, this time sending the change request selected as a parameter. We do not need to run the AJAX call when the change field value or newValue is empty, but this time, we do want our script to run on load, so we have removed the isLoading check from the beginning of the script. 

When we return from the AJAX call, we are using g_form to show a field message which appears just below the field to show whether the change request selected has open tasks or not. 

Now we'll take a look at the server-side script that makes this AJAX call work. A script include will be used to hold the code:

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

/**
* Ajax Call - Returns whether a change has open tasks
*/
changeHasOpenTasks: function changeHasOpenTasks() {

var cTask = new GlideRecord('change_task');
cTask.addQuery('change_request', this.getParameter('sysparm_change'));
cTask.addQuery('state', 'NOT IN', '3,4'); //Closed and Cancelled
cTask.query();
if (cTask.next()) {
return true;
}
return false;
}
});

In the server-side script for this example, we are using a GlideRecord to find all the change tasks that are still open for the change request we passed in as a parameter. In the preceding script, we are using an addQuery line for the GlideRecord where the state is not 3 or 4, which equates to closed and canceled. This allows us to treat any other state as open, even if further active states have been added from the out-of-the-box setup.

This means that if any record is found, we can return true immediately, as we only need to know that at least one task is still open. There is no point in running through other change tasks if we find one that is still open, and this keeps the processing time down and the code more efficient.

Once the return value is sent back, the corresponding field message will display to the user using the client-side code. This type of AJAX call can be very useful for giving users extra detail on forms about the data they are entering.

The AJAX call is widely used, and I would certainly recommend becoming acquainted with it as early as possible for scripting in ServiceNow, as many requirements will need an AJAX call so they can be fulfilled. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.144.32