orking in Service-now, you’ll find that a lot of scripting tasks come down to identifying which fields changed on a form (client-side) or record (server-side). In this post, I’ll show you some different techniques to identify changed fields in both client-side, and server-side scripts. I’ll also show you a way that you can capture changed fields and values and print them in an email notification…without having to check every potential field in a record.

ServiceNow - Changed Fields

Identifying modified or changed fields in Client scripts

When looking at a form in Service-now, it’s usually pretty easy to identify the fields that have changed since the form loaded (as seen in the screen shot above). The green field indicators give a simple visual cue to the user. Behind the UI, the system is taking cues as well and firing off ‘onChange’ events and setting field parameters as a result. When you write on ‘onChange’ client script or a UI policy, you can tie into the events and take actions as a result. If at all possible, you should stick to ‘onChange’ client scripts or UI policies.
There are some special situations (typically on submission of a record) where you don’t have a special event that tells you something changed. In an ‘onSubmit’ scenario, you have to check for these changes yourself. A great example of this can be used is the ‘Dirty form’ navigation property (glide.ui.dirty_form_support) that can be turned on to display a message to users if they navigate away from a ‘dirty’ or changed form without first saving the record.

Client Script examples
If you just want to do a check to see if any value on the entire form changed (a dirty form), you can use ‘g_form.modified’ in an ‘onSubmit’ client script like this…

function onSubmit() {
    return confirm("Values on the form have changed.\nDo you really want to save this record?");

If you just want to check for changes to a few specific fields then you could use something like this in an ‘onSubmit’ client script…

function onSubmit() {
  var field1 = g_form.getControl('caller_id'); //Get the 'Caller' field control
  var field2 = g_form.getControl('short_description'); //Get the 'Short description' field control
  //See if the 'changed' attribute on either field is true
  if(field1.changed || field2.changed){
    return confirm("Values on the form have changed.\nDo you really want to save this record?");

Checking for changes to variables is a bit more complex because the underlying element changes names. This script will check an individual variable…

var el_id = g_form.getControl("requested_for").id;
var orig_val = gel("sys_original."+ el_id).value;
var new_val = g_form.getValue("requested_for");
if(orig_val != new_val){
   alert("It's changed");

This script will check for all of the variables on the form to see if they have the ‘changed’ CSS class. It will return a count, so any count greater than 0 means that something on the form has been modified…

if($$('.changed').length > 0){
   return confirm("Values on the form have changed.\nDo you really want to save this record?");

Identifying modified or changed fields in Business rules

Business rules are server-side scripts, so there’s no form, no green indicator, and no ‘onChange’ event to tell you what happened. In these scenarios, business rules just care about what’s on its way to the record in the database.
Service-now includes some simple convenience methods for identifying changes to a record or field in a business rule. You may have seen these used in the ‘Condition’ field on many of the out-of-box business rules. All of the methods below return true or false based on changes to the ‘current’ record.

Record change: current.changes();
Field change: current.YOUR_FIELD_NAME_HERE.changes();
Field changes TO a value: current.YOUR_FIELD_NAME_HERE.changesTo(VALUE);
Field changes FROM a value: current.YOUR_FIELD_NAME_HERE.changesFrom(VALUE);

But what if you don’t know in advance what might change? What if you just need to return a list of changed fields or values? This might be one field, or 30 fields! I recently discovered the ‘GlideScriptRecordUtil’ class can get this type of information for you. You can use the following methods in a ‘before’ or ‘after’ business rule.

var gru = GlideScriptRecordUtil.get(current);
gru.getChangedFields(); //Returns an arrayList of changed field elements with friendly names
gru.getChangedFieldNames(); //Returns an arrayList of changed field elements with database names
gru.getChanges(); //Returns an arrayList of all change values from changed fields
Business Rule example
You can paste this script into a ‘before’ business rule on any table to display information messages about changed fields. This isn’t terribly useful, but does do a good job of showing how you can process changed field results.

//Display an information message for each change to the record
var gru = GlideScriptRecordUtil.get(current);
var changedFields = gru.getChangedFields(); //Get changed fields with friendly names
var changedValues = gru.getChanges(); //Get changed field values
//Convert to JavaScript Arrays
changedFields = j2js(changedFields);
changedValues = j2js(changedValues);

//Process the changed fields
for(var i = 0; i < changedValues.length; i++){
   var val = changedValues[i];
   if(val.getED().getType() == -1 && val.getJournalEntry(1)){
      //Print out last journal entry for journal fields
      //Print out changed field and value for everything else
      gs.addInfoMessage(changedFields[i] + ': ' + val.getDisplayValue());

ServiceNow Changed Fields Business Rule

Printing all record changes in an email notification

One common use case I’ve seen for collecting all record changes in an update is to send all of those changes in an email notification. Without the use of the ‘GlideScriptRecordUtil’ methods described above, this really wasn’t practical. Here’s a solution I’ve come up with that allows you to accomplish this…

The first part is gathering these changes when you trigger your email notification event. Because the changes need to be captured at the time the record is updated or inserted, this needs to happen in a business rule. This script example collects all changed fields on an incident record and passes them as an event parameter to the ‘Incident Assigned to my Group’ notification.

//Collect all changed fields
var gru = GlideScriptRecordUtil.get(current);
var fields = gru.getChangedFieldNames(); //Get changed fields with database names
//Convert to JavaScript Array
fields = j2js(fields);

if (!current.assignment_group.nil() && current.assignment_group.changes()) {
   gs.eventQueue("incident.assigned.to.group", current, fields , '');

Once you’ve passed the event (with the changed fields parameter) to your notification, you can set up a mail script to iterate through the changed fields and print the results to the outgoing email.

One thing you’ll want to be careful of here is read access to the fields and values you’re printing out. There’s not a simple way to determine who should be able to read these fields in an email notification so if you’re sending an email to end users, you probably want to specify individual fields in a more targeted technique.
Changed fields:
//Process the changed fields
var fields = event.parm1.split(',');
for(x in fields){
   //Get the field label, value, and type
   var field = fields[x];
   var fieldLabel = eval('current.' + field + '.getLabel()');
   var fieldVal = eval('current.' + field+ '.getDisplayValue()');
   var fieldType = eval('current.' + field + '.getED().getType()');

   if(fieldType == -1 && eval('current.' + field + '.getJournalEntry(1)')){
      //Print out last journal entry for journal fields
      template.print(eval('current.' + field + '.getJournalEntry(1)'));
      //Print out changed field and value for everything else
      template.print(fieldLabel + ': ' + fieldVal + '\n');

The result of this mail script will look something like this…
Email Changed Fields