Your Changes Will Be Lost If You Leave Now

We’ve all seen it. We’ve all scratched our heads when ServiceNow tells us that fields have been changed, but we don’t think so because we know the page just loaded or that no changes were made. We’ve all slowwwwwly clicked Leave or Discard and hoped we were right. How could we possibly know?

Next UI
UI16
Yet Another Confirm

There are probably 100 ways to identify why ServiceNow is telling us this, but I solved it in a very specific way one day while looking through the GlideForm class. If you’ve been in the ServiceNow ecosystem long enough, you’ll know that there’s a lot more to much of ServiceNow’s codebase than what they include in their API docs. Once in a while someone in Community will share a function that was previously hidden from the masses, a snippet of incredibly useful functionality that makes you slap your forehead and curse at the docs maintainers.

Back to the GlideForm class… I was looking through the previously-linked script and noticed this little gem: modifiedFields. I had never seen this documented, but thought it might be useful if I could understand it better.

First, we can see that it’s an object based on the initialization of the GlideForm class:

First Mention of modifiedFields

modifiedFields isn’t mentioned many times in this script, but the mentions it does have highlight a bit of the structure of this object:

The Rest of the modifiedFields Mentions

fieldChanged() shows us that the modifiedFields object contains an element name and a value of true or false. (We could, of course, figure this out in other ways, too.)

_checkModified() is a private function used by fieldChanged().

That’s it – those are the only times that modifiedFields is mentioned in GlideForm.

I wanted a way to make this useful. Among ServiceNow’s other hidden gems is the JavaScript Executor. To bring up the JavaScript Executor, on a form or list (maybe other places, too, but it’s not as obvious to me why you would need it elsewhere) simply press “CTRL+SHIFT+J” to see the following:

I always use CTRL+SHIFT+JJ, but one J seems to work the same

In this window we can execute whatever client-side JavaScript we want – alert(), g_form, etc. I consider this similar to a background script in that arbitrary code can be executed, but on the client side. (There are some other features of this window that I rarely use, but I’ll dig into at some other point.)

Back to my original problem that needed a solution. Occasionally, I get an alert stating that a form has been modified and that if I navigate away, the changes will be lost. I frequently don’t know what this change is, but I want to know what changed to be sure.

In the JavaScript Executor, I typed a simple command:

alert(g_form.modifiedFields);

I didn’t really expect this to work, but it’s a stepping stone:

First Attempt to Figure This Out

We know from our previous investigation that modifiedFields is an object, so we need to treat it as such when trying to see its contents:

alert(JSON.stringify(g_form.modifiedFields));

We’re getting somewhere!

Second Attempt to Figure This Out

This is a lot better! We can actually see the field that was modified. If there were multiple modified fields, it would appear like this:

Second Attempt, but with Multiple Fields

Functional, but not pretty. I’d like to see each field separately. And we know that the value is doing to be “true”, so that’s mostly useless. I wouldn’t want an alert() for each field (there could be dozens, after all), so let’s split the results and use another client side method to make it prettier. We can also add some more flair to it to make it really shine.

var changed = '';

if (Object.keys(g_form.modifiedFields) != '') {
    var obj = g_form.modifiedFields;
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            g_form.addDecoration(i.split('.')[1], 'icon-star', 'Changed', 'color-red');
            g_form.flash(i, 'yellow', -4);
        }
    }
    changed = Object.keys(g_form.modifiedFields);
}

g_form.addInfoMessage(changed);

Well, that escalated quickly.

Third Attempt, with Pizzazz!

This is so incredibly useful! And pretty! But to make it reusable, it really needs to be a UI Action. (⬅️ Foreshadowing)

A context menu UI action would make this really useful and visible in many of the most frequent destinations in the platform. The following script can be placed in the Script box of a UI Action, check the “Client” checkbox, and call the function in the “Onclick” box.

The Final Solution

This solution has actually been available as a UI Action in Share for a couple years now. You can find it all packaged up here: What changed? This could easily be limited to certain users (admin only?) or adjusted with different colors, icons, verbiage, etc.

There are a handful of extra features I add into almost every instance I touch, and this is one of them. Hopefully you’ll find it useful and your forehead will be a little less sore in the future!

2 thoughts on “Your Changes Will Be Lost If You Leave Now

Leave a Reply