Some time ago we showed you how to refresh the left navigation pane via a script. The server-side solution in that article utilizes ServiceNow’s UINotification object/class. On versions prior to Calgary, this is the Java class Packages.com.glide.ui.UINotification.
There’s another use for UI notifications. In addition to refreshing the left navigator, the object can also be used to display informational messages. You’ve probably already seen these in your own instance. When you change update sets, the system reminds you by using a UI Notification similar to the one shown below:
If you’re like me, you may have wondered how these notifications are created. Displaying a custom UI notification is slightly more complex than using the addInfoMessage() method provided by the GlideSystem (server) and GlideForm (client) classes. In return, it gives you some capabilities that aren’t otherwise available. These include options to set fade-in and fade-out effects and the ability to make the notification persistent or to close it after a user-specified interval. If you want to learn more about the various types of notifications available in ServiceNow, check out our UI Info and Error Message Cheat Sheet.
The example below uses the UINotification object to display a list of all fields that have been changed on an incident. I’d like to take credit for this solution, but it was actually my colleague Jim Coyne who did the heavy lifting. I’m most especially indebted to him for compiling the all-important list of option properties that determine how the notification behaves.
Creating The Notification
To create the UI Notification and its options, use a global UI Script:
Name: Popup UI Notification
Active: true
Global: true
Description: Adds a popup UI Notification to the DOM. Can be called from any server-side script. For an example, see ‘Changed Fields UI Notification’ business rule on the Incident table.
Script:
var intervalTest = setInterval(function(){
if(typeof CustomEvent != 'undefined'){
clearInterval(intervalTest);
setCustomEvents();
}
},500);
//Add the UI Notification to the DOM using the CustomEvent object
function setCustomEvents(){
//Set the name of the notification
var notifName = "demo_notification";
CustomEvent.observe('glide:ui_notification.' + notifName,
function(notification){
var msgText = notification.getAttribute('text1'); //get the message text from the attribute passed in by the business rule
var options = {}; //create a new object to store all of the message attributes.
options.text = "<span style='color:red;'>" + msgText + "</span>";
options.sticky = true;
options.closeDelay = 5000;
options.fadeIn = 500;
options.fadeOut = 500;
new NotificationMessage(options); //display the UI Notification
});
}
The CustomEvent object takes two arguments:
- The ‘glide:ui_notification.‘ object. This object includes a mandatory property that defines its name. In our example we’ve used a variable to store the name, but it could also be added to the object as an explicit value. In that case, it would be written ‘glide:ui_notification.demo_notification’ (including the quotes).
- A function that defines the notification’s contents and display options. The display options determine how the notification will behave. The options should be defined as properties in their own options object within the function. Available options properties include:
text: Required. The text of the message. You can include rich text formatting via standard HTML tags.
sticky: Optional. If true, the notification persists until the user closes it by clicking the [x] icon. If false or omitted, the notification automatically closes after the specified closeDelay.
closeDelay: Optional. Automatically closes the message after this number of milliseconds. If omitted, the message closes after about three seconds. If the sticky property is true, this option is ignored.
fadeIn: Optional: Sets the fade-in time for the notification in milliseconds
fadeOut: Optional: Sets the fade-out time for the notification in milliseconds if the sticky property is false/omitted. If the sticky property is true, this option is ignored.
The function uses the getAttribute() method to retrieve the information passed in from the server-side script which triggers the notification. If multiple attributes have been set in the server-side script, the UI Script will need additional getAttribute() method calls to retrieve each one.
Displaying the Notification
To display the notification, we simply instantiate, (create a new instance of) the UINotification object in a Business Rule (it may work in other server-side scripts but I haven’t tested that). For our example we’ll use a business rule that runs after the incident has been updated. Our script borrows code from a previous post about checking for modified fields on forms or records.
Name: Changed Fields UI Notification
Table: Incident [incident]
Active: true
When: after
Update: true
Script:
if (typeof GlideScriptRecordUtil != 'undefined') {
var gru = GlideScriptRecordUtil.get(current);
} else {
var gru = Packages.com.glide.script.GlideRecordUtil.get(current);
}
var changedFields = gru.getChangedFields(); //Get changed fields with friendly names
//Next, pass the values into the UI Notification we defined in the UI Script
var notification;
if(typeof UINotification != 'undefined') {
notification = new UINotification('demo_notification'); //Calgary and later releases use the UINotification object call
} else {
notification = new Packages.com.glide.ui.UINotification('demo_notification'); //For pre-Calgary releases, use the Java Package call
}
//create the message to be displayed
var messageText = gs.getUser().getDisplayName();
messageText += ' modified the following fields on : ';
messageText += current.number;
/*
Assign the message text to the 'text1' attribute. Additional attributes can be passed into the UI notification. Just be sure each one is accounted for in the UI Script via getAttribute() method calls.
*/
notification.setAttribute('text1', messageText + changedFields);
notification.send();
The key items in the business rule’s script are:
- The new UINotification object call that specifies the object we defined in the UI Script (‘demo_notification’)
- The setAttribute() method that passes specific information into the notification
- The send() method that triggers the actual display of the notification.
To see the notification, open any Incident and modify one or more fields, then Save or Update it.
Once the UI Script is defined, it can be reused as many times as needed. Just call it from any business rule and pass information to it using the setAttribute() method.
Very nice, but how do you guys always find out what is included in the classes like UINotification and GlideScriptRecordUtil? Is there some kind of web decompiler?
Mostly its just a lot of sleuthing Oliver– Examining other out-of-box scripts that use the function can give you clues, especially if the function is defined in a Script Include. Using your browser’s developer/web tools to view the source for the page is also a good way to find information about some of these undocumented functions. Sometimes you can even get information from ServiceNow technical support, though they’re always quick to note that these functions are not officially supported. Really it just boils down to doing a lot of digging and then experimenting with things until you get it right.
One needs to be careful though when using these undocumented API’s. ServiceNow can change the API between releases since its not a supported public interface. I was bitten by that on an upgrade from Aspen to Berlin.
Right you are Paul, and thanks for that reminder. I’ve added an advisory note to the article.
Great stuff Jim, There is a Syntax error on Line 17 “UI SCRIPT”
options.text = “” + msgText + “”;
Thanks Steven. I’ve updated the code.
Pretty sure this only works in BR’s. Tried Script include and scheduled job, no luck. Works fine in business rules though.
I suppose that’s what I get for assuming, Nick. Admittedly I haven’t tried this out anywhere other than in a business rule. I can’t think of any reason why it wouldn’t work in any other server-side script, but it’s certainly possible. I’ll update the post to note that.
I am trying to use this as a session timeout message, I am going to try a script action. I cannot use a business rule because I want this message to fire without a database action, from the server because I wanted to fire this before session timeout. Grr. this is driving me nuts.
n = new UINotification(‘demo_notification’);
n.send();
Any ideas would be great!!
Ok so for anyone that needs an idea for this here is what I did-
Global UI Script that runs on interval calling a script include Ajax, which in turn queries the v_user_session table, field ‘last_transaction’. Compare that to the current time, and then against whatever your system timeout property is. Ours is the default 30 minutes. If the difference is almost thirty minutes return the username from the user session table, and then invoke the n= new UINotification(answer + ‘ your session is about to expire, save your work ! ‘ ) from the UI Script. Only way I could figure to “schedule” this. Couldn’t get this to work in script action, script include , scheduled job. Just on the client (obviously) and business rules. If anyone knows why this only works in BRs that would be great to know!
It works fine in a Script Include for me (on Fuji). You should reload the entire screen (not just the form) after adding the UI Script.
Does someone try to use above UI Script and Business Rule? I created exactly the same items but had no luck with pop-up message displaying
Hi!
Nice article.
I have tried this, but the notification only showed up for the Updater. I need to make the notification shown for the other agents (or a specific role).
Did I miss something?
I have to add my voice to that one, it’s not clear how to control who will get the notification… other than that this is really useful.
Joining Nadya and Russell on that – is it possible to show such a notification to all connected users, and not only to the one who made the changes?
I hope someone comes up with an easier way to do this. It seems like a lot of code for such a simple feature. Anyone?
Is there a way to make these message pop-up and display for all users that are currently logged into SN?
Did anyone get this to work with UI16 ?
Hi Michael,
It appears that ServiceNow provides a new g_notification object, GlideNotificationV3. According to the documentation it only works with ListV3.