Client Scripts

From ServiceNow Wiki
Home > Script > Client Scripts > Client Scripts
Jump to: navigation, search
Note
Note: This article applies to Fuji. For more current information, see Client Scripts at http://docs.servicenow.com

The ServiceNow Wiki is no longer being updated. Visit http://docs.servicenow.com for the latest product documentation.


1 Overview

Client scripts are shipped to the client (the browser) and run there instead of on the server. Users who know JavaScript can define scripts to run in the client browser. Several types of scripts are supported:

Script type Runs when
onLoad() The system loads a form
onChange()
  • The system loads a form loads and no field values have changed
  • A field value changes
onSubmit() A user saves the form
onCellEdit() A list cell value changes
Note
Note:
  • For optimal performance, the recommended best practice is to limit the amount of code sent to the client. Consider the impact on the client when adding client scripts.
  • Client scripts are not supported on search screens.



Warning
Warning: With the exception of onCellEdit client scripts, UI policies and client scripts apply to forms only. If you create UI policies or client scripts for fields on a form, you must use another method to ensure that data in those fields is similarly controlled in a list. You can:

See Setting Field Values in Forms and Lists for a comparison of client scripts and business rules.

2 Client Script Form

To define a client script, navigate to System Definition > Client Scripts and create or edit a record (see table for field descriptions).

You can add client scripts only on tables that are in the same scope as the client script (starting with the Fuji release).

Image:client_script.png

Field Description
Name Unique, descriptive name for this script.
Application Application that contains this client script (starting with the Fuji release).
Active Indicator of whether the script active.
Global Indicator of whether the script applies to all views. When Global is selected, the script runs regardless of what view is being displayed. When Global is not selected, the script runs only if the current view matches the value in the View field.
View View the script applies to. This option is available only if Global is not selected.
Type Indicator of when the script runs. Select one of the following types:
  • onLoad(): when a form is first loaded.
  • onSubmit(): when a form is submitted. This type allows you to cancel the submission, if necessary.
  • onChange(): when a particular field on the form changes value or when a form is first loaded and no fields have changed values.
  • onCellEdit(): when a user interacts with a specified field in a list.
Table Table or database view this script applies to, such as Incident or Change Request.


Note
Note: The list shows only tables and database views that are in the same scope as the client script (starting with the Fuji release).
Inherited Indicator of whether the script applies to extended tables. For example, if the script is active on the task table, selecting Inherited runs this script on the incident, change_request, and problem tables, as well.
Field name Field the script applies to. This option is available only if the Type is set to onChange()
Description Detailed description of the client script.
Messages Text strings available to the client script. Enter one string per line using getMessage(msg) syntax. You can use these strings in the client script as localized messages without an AJAX call, which allows for the internationalization of messages without a round trip to the server. As an example, if the Message field has the line Please populate the Reason field, and an entry exists in the sys_ui_message table for their language with that key, then the client script could have the following line:
alert(getMessage(Please populate the Reason field));

and the user would see it in their language.

Script Script that executes when the client script is triggered.
UI Type Target UI this script applies to: Desktop, Mobile, or Both (starting with the Dublin release).
Related lists on the form view:
Versions All versions of the client script. Use this list to compare versions or to revert to a previous version. See Versions.

3 Client Script Types

3.1 onLoad() Scripts

An onLoad() script runs when a form is first drawn and before control is given to the user to begin typing. Typically, you use an onLoad() script to perform some client side manipulation of the document on screen.

An onLoad() script must contain a function named onLoad(). Otherwise, it is entirely up to you what your script does after it gets to the client.

For example, here is a trivial onLoad() script that displays a message box that says "Loading ..." while the page loads.

function onLoad() {
  alert('Loading ...');
}

3.2 onSubmit() Scripts

An onSubmit() script runs when a form is submitted. Typically, you use an onSubmit() script to validate things on the form and ensure that the submission makes sense. As such, onSubmit() scripts can potentially cancel a submission by returning false.

An onSubmit() script must contain a function named onSubmit().

For example, here is an onSubmit() script that prompts the user to confirm that a priority one ticket should really be submitted. If the user clicks Cancel in the confirmation dialog box, the submission is canceled.

function onSubmit() {
  var priority = g_form.getValue('priority');   
  if (priority && priority == 1)
  return confirm('Are you sure you want to submit a priority one ticket? The CIO will be notified!');}
}

The important thing to remember here is: to stop form submission, return false from your onSubmit() script.

3.3 onChange() Scripts

An onChange() script can run when a particular field changes value or when the form is first drawn and no fields have changed value from previous script actions. As such, onChange scripts can potentially act as onLoad scripts with extra conditions.

An onChange() script must contain a function named onChange().

All onChange() scripts are called with several parameters:

  • control - the field whose value changed if any.
  • oldValue - the value of this widget when the record was loaded into the form.
  • newValue - the value of this widget after the change, or when the isLoading parameter is true, the same value as the oldValue parameter.
  • isLoading - identifies whether the form is loading and also indicates that no fields have changed value. This parameter can only be true when the form is loading and no values have changed.
  • isTemplate - identifies whether the change occurs as part of a template load or not.

For example, here is an onChange() script that notifies the user whenever the short description field on a form changes.

function onChange(control, oldValue, newValue, isLoading) {
  alert('you changed short description from ' + oldValue + ' to ' + newValue);
}

To prevent an onChange() script from running when the form loads, add the following condition to the top of the script.

if (isLoading) {
  return;
}

3.4 onCellEdit() Scripts

Scripts can be defined as onCellEdit to run on the client side when the list editor interacts with a cell.

Note
Note: onCellEdit scripts do not apply to list widgets on homepages or dashboards.


An onCellEdit() script must contain a function named onCellEdit().

An onCellEdit() script takes the following parameters:

  • sysIDs - An array of the sys_ids for all items being edited.
  • table - The table of the items being edited.
  • oldValues - The old values of the cells being edited.
  • newValue - The new value for the cells being edited.
  • callback - A callback that continues the execution of any other related cell edit scripts. If 'true' is passed as a parameter, the other scripts are executed or the change is committed if there are no more scripts. If 'false' is passed as a parameter, any further scripts are not executed and the change is not committed.

Example:

function onCellEdit(sysIDs, table, oldValues, newValue, callback) {
  var hasDifferentValues = false;
  for (var i = 0; i < oldValues.length; i++) {
    var oldValue = oldValues[i];
    if (oldValue != newValue){
      hasDifferentValues = true;
      break;
    }
  }
  var success = hasDifferentValues && performSomeFurtherValidation(sysIDs, table, oldValues, newValue); 
  callback(success);
}

4 Client Script FAQ

4.1 Why do I have to name scripts like that?

The client code needs to know which function to attach to the document. Hence, it requires that you follow our naming convention with functions. Note that you can have more than one function on a client side script and have your onSubmit() function, for example, call other functions. The requirement is that the primary function follow our naming convention.

4.2 Can I have more than one function listening to the same thing?

You can, but there is no guarantee of sequencing. You cannot predict what order your event handlers will run.

4.3 How do I reference a field on the form?

To reference the actual HTML element of the priority field on the incident form:

var priority_field = g_form.getControl('priority');

The easiest way to reference a field's value is to use the built-in g_form helper variable:

var value_of_priority = g_form.getValue('priority');

4.4 How do I cancel a form submission?

Have your onSubmit() function return false. For example the following snippet of code disallows all form submission.

function onSubmit() {
  return false;
}

4.5 How do I confirm a field value with the user?

function onSubmit() {
  //This allows you to access fields from the referenced record
  var assignedTo = g_form.getReference('assigned_to');
  var answer = confirm("The Assigned to is " + assignedTo.user_name + ". Is this correct?");
  if (answer == true) {
    return false;
  }
}

4.6 How do I force a Save and Stay?

// onChange event on Incident table using Field name "Caller"
function onChange(control, oldValue, newValue, isLoading) {
  // Setting the control value prevents against an infinite loop 
  // Change caller_id to the field the change event reacts to
  if(control.caller_id != newValue && control.caller_id != null) { 
    //do any comparisons you want 
    //
    // . . .
    //
    //does an update and stay
    gsftSubmit(document.getElementById('sysverb_update_and_stay'));
  }
  // Change caller_id to the field the change event reacts to 
  control.caller_id = newValue; 
}

4.7 How do I call a business rule from a client script?

To call a business rule from a client script, use GlideAjax.

4.8 What are some of the available helper functions?

There is a global object that ServiceNow automatically creates called g_form that references the currently active form. You can use the g_form object in your scripts to simplify certain common programming tasks.

A second global object, called g_user, references the currently active user. Just like g_form, you can use g_user in your scripts to react based on the current user (and that user's roles).

4.8.1 Hide or show a field

While you can use client scripting to hide or show a field, you can usually accomplish the same thing without scripting via UI policies.

g_form.setVisible(<fieldname>, <value>);
function onChange(control, oldValue, newValue, isLoading) {         
  var index = newValue.indexOf('Change');
  if (index == -1) {
    // hide it
    g_form.setVisible('field', false);
  } else {
    // unhide it
    g_form.setVisible('field', true);
  }
}

4.8.2 Make a field mandatory

While you can use client scripting to make a field mandatory, you can usually accomplish the same thing without scripting via UI policies.

g_form.setMandatory(<fieldname>, <value>);
function onChange(control, oldValue, newValue, isLoading) {
  if (oldValue == newValue)
    return;
  g_form.setMandatory('short_description', true);
}
  function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading)
      return;

    if (newValue == "Critical")
      g_form.setMandatory('u_due_date', true);
    else
      g_form.setMandatory('u_due_date', false);
}

4.8.3 Make a field read-only

While you can use client scripting to make a field read-only, you can usually accomplish the same thing without scripting by using UI policies.

In order to make a field read-only, the field must be present on the form, though it may be hidden. The following example makes the incident_state field read-only on the Incident form upon load:

function onLoad() {
  g_form.setReadonly('incident_state',true);
}

To do the same thing for a derived field (e.g., the Caller's phone number field if it has been added to the Incident form), you can use the following:
function onLoad() {
  g_form.setReadonly('caller_id.phone', true)
}

4.8.4 Get a field value

g_form.getValue(<fieldName>);
function onChange(control, oldValue, newValue, isLoading) {
  alert(g_form.getValue('short_description'));
}

4.8.5 Set a field value

g_form.setValue(<fieldName>, <value>);
function onChange(control, oldValue, newValue, isLoading) {
  g_form.setValue('short_description', 'hello world');
}

4.8.5.1 Set a glide_list field value

You can pass one argument or two. For reference values, passing both the sys_id and the display value is more efficient because the client does not have to look up the display values for you. However, if you do not want to pass the display value, the client will do an AJAX call to find the value, which takes time.

Example: reset to no values:

g_form.setValue("watch_list", "");

Example: Set to two references, passing the display values to avoid an AJAX call
var valueArray = new Array("46d44a23a9fe19810012d100cca80666", "46c6f9efa9fe198101ddf5eed9adf6e7");
var labelArray = new Array("Beth Anglin", "Bud Richman");
g_form.setValue("watch_list", valueArray, labelArray);

Example: Set arbitrary email address (for a sys_user glide list)
g_form.setValue("watch_list", "", "you@you.com");

Example: Set references and emails, passing the display values to avoid an AJAX call
var valueArray = new Array("46d44a23a9fe19810012d100cca80666", "", "46c6f9efa9fe198101ddf5eed9adf6e7");
var labelArray = new Array("Beth Anglin", "me@me.com", "Bud Richman");
g_form.setValue("watch_list", valueArray, labelArray);

Example: Set references and emails, but use AJAX to obtain display values for references (this is a bit less efficient as the server must be contacted for the display values)
var valueArray = new Array("46d44a23a9fe19810012d100cca80666", "me@me.com", "46c6f9efa9fe198101ddf5eed9adf6e7");
g_form.setValue("watch_list", valueArray);

Example: Set references and emails using a comma separated string, but use AJAX to obtain display values for references (this is a bit less efficient as the server must be contacted for the display values)
g_form.setValue("watch_list", "46d44a23a9fe19810012d100cca80666,me@me.com,46c6f9efa9fe198101ddf5eed9adf6e7");

4.8.6 Add an Option to the end of a choice list

g_form.addOption(<fieldName>, <choiceValue>, <choiceLabel>);
function onChange(control, oldValue, newValue, isLoading) {
  g_form.addOption('priority', '6', '6 - Really Low');
}

4.8.7 Add an Option at a specific point on a choice list

g_form.addOption(<fieldName>, <choiceValue>, <choiceLabel>, <targetIndex>);
function onChange(control, oldValue, newValue, isLoading) {
  g_form.addOption('priority', '2.5', '2.5 - Really Low', 3);
}

Note that an insert happens at the location you specify on a zero based array. Existing options will all shift up one level. For example, given:

[A, B, C, D]

Insert E at 0

[E, A, B, C, D]

Insert E at 2

[A, B, E, C, D]

4.8.8 Remove an option from a choice list

g_form.removeOption(<fieldName>, <choiceValue>);
function onChange(control, oldValue, newValue, isLoading) {
  g_form.removeOption('priority', '1');
}

Remove the Closed state option if the user is not an admin:

function onLoad() {
  var isAdmin = g_user.hasRole('admin');
  var state = g_form.getValue('state');
  if (!isAdmin && (state != 7)){
    //alert('Current user is not an admin');
    g_form.removeOption('state', '7');
  }
}

4.8.9 Remove ALL options from a choice list

The Category choice list, for example:

g_form.getControl('category').options.length = 0;

4.8.10 Get the label for a choice list value

var choiceValue = g_form.getValue(<fieldName>);
var choiceLabel = g_form.getOption(<fieldName>, choiceValue).text;
function onChange(control, oldValue, newValue, isLoading) {
  var choiceValue = g_form.getValue('category');
  var choiceLabel = g_form.getOption('category', choiceValue).text;
}

4.8.11 Show or hide an action button depending on the form view

function onLoad() {
  var objView = document.getElementById('sysparm_view');
  var strView = objView.getAttribute('value'); 
  if (strView == 'ess') {
    var objCloseButton = document.getElementById('close_incident');
    objCloseButton.style.display = 'none';
  }
}

4.8.12 Look up the value of a reference field

var gr = g_form.getReference('fieldName');
function onChange(control, oldValue, newValue, isLoading) {
  var caller = g_form.getReference('caller_id');
  if (caller.vip == 'true')
    alert('Caller is a VIP!');
}
Note
Note: When setting values, use the storage value instead of the display value.


4.8.13 Get the current user name

var myVariable = g_user.userName;
function onLoad() {
  var userName = g_user.userName;
  alert('Current user = ' + userName);
}

4.8.14 Get the value of a parameter

var currentView = g_form.getParameter('view');
function onLoad() {
  var view = g_form.getParameter('view');
  alert('Current view = ' + view);
}

4.8.15 Test if the current user has a role

var myRole = g_user.hasRole(<role>);
function onLoad() {
  var isAdmin = g_user.hasRole('admin');
  if (isAdmin)
    alert('Current user is an admin');
  else
    alert('Current user is NOT an admin');
}

4.8.16 Determine what submit button was clicked

function onSubmit() {
  var action = g_form.getActionName();
  alert('You pressed ' + action);
}

4.8.17 Determine if any fields on the form have changed

function onSubmit() { 
  var field1 = g_form.getControl('caller_id');
 
  //See if the 'changed' attribute is true
  if(field1.changed){
    return confirm("The Caller field has changed.\nDo you really want to save this record?");
  }
}

4.8.18 Using GlideRecord query from client

There is a lightweight GlideRecord object on the client side that can be used to query the server from within client scripts. For details, see Client-side GlideRecord. The following are some common methods that are available.

  • addQuery()
  • get()
  • hasNext()
  • next()
  • orderBy()
  • query()

One limitation is that the addOrCondition() method is not available. You can work around this by setting the GlideRecord encodedQuery property with an encoded query string.

Example:

var cat = g_form.getValue('category');
var subcat = g_form.getValue('subcategory');
var lookup = new GlideRecord('u_assignment_lookup');
strQuery = "u_type=Incident^ORu_type=All";
strQuery = strQuery + "^u_category=" + cat;
strQuery = strQuery + "^u_subcategory=" + subcat;
strQuery = strQuery + "^EQ";
lookup.encodedQuery = strQuery;
lookup.query();

4.8.19 Check if order guide is loaded for the first time

It can be helpful for a catalog client script to know whether the user has just started an order guide or is going back to the guide using the Describe Needs button from the item page.

// onload catalog script
if (g_form.getParameter('cart_edit')!='guide_serial') {
  // this stuff only runs if the guide is reloaded after initial submit
  // it will not run on initial load of the guide
}

5 Enhancements

5.1 Fuji

  • These changes support developing scoped applications:
    • The Table field shows only tables and database views that are in the same scope as the client script.
    • The Application field is added on the form view.
Was this article helpful?
Yes, I found what I needed
No, I need more assistance