
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 03-01-2020 08:01 PM
ServiceNow provides a client-side API called GlideModal but the documentation is focused around displaying records or lists from ServiceNow. There are times where you'd like to use a custom form with just a few options. In this example, we're adding a UI Action button to the catalog task form so when a task is cancelled we can either:
- Closed skipped - effectively cancelling just this task
- Closed incomplete - close this and all other tasks along with the requested item itself
In this way, we're giving our users the ability to clearly determine what they're cancelling. Just one particular task or the whole thing.
UI Actions allow you to run code client-side and server-side, which is very handy.
The key to getting some flexibility with your modal dialog is the renderWithContent which allows us to craft our own HTML and the window.changeTaskAction which allows us to interpret whatever happened on our modal as the user interacted with our options.
////////////////////////////////////////////////////////////////
//Client Side: Dialog box with choices
////////////////////////////////////////////////////////////////
function cancelDialog(){
var gm = new GlideModal('cancelTask');
//Sets the dialog title
gm.setTitle('Cancel Task');
//Set up valid custom HTML to be displayed
gm.renderWithContent('<div style="padding:15px"><p>What action do you want to take?</p><p><select name="cancellation" id="taskCancellation" class="form-control"><option value="cancelOnly" role="option">Cancel this task but keep the requested item open</option><option value="cancelAll" role="option">Cancel this and all other tasks, closing the requested item</option></select></p><div style="padding:5px;float:right"><button style="padding:5px;margin-right:10px" onclick="window.changeTaskAction(this.innerHTML,jQuery(\'#taskCancellation\').val())" class="btn btn-default">Abort</button><button style="padding:5px" class="btn btn-primary" onclick="window.changeTaskAction(this.innerHTML,jQuery(\'#taskCancellation\').val())">Cancel Task</button></div></div>');
//We'll use the windows object to ensure our code is accessible from the modal dialog
window.changeTaskAction = function(thisButton, thisAction){
//Close the glide modal dialog window
gm.destroy();
//Submit to the back-end
if(thisButton=='Cancel Task'){
if(thisAction=="cancelAll"){
g_form.setValue('state',4);//Closed Incomplete -- will close the Requested Item and all other open tasks
}else{
g_form.setValue('state',7);//Closed Skipped -- will only close this task
}
//Regular ServiceNow form submission
gsftSubmit(null, g_form.getFormElement(), 'cancel_sc_task');
}
};
return false;//prevents the form from submitting when the dialog first loads
}
////////////////////////////////////////////////////////////////
//Server Side: Dialog box with choices
////////////////////////////////////////////////////////////////
if (typeof window == 'undefined')
updateTask();
function updateTask(){
//Runs on the server
if(current.state==7){
//closed skipped so simply update this one record
current.update();
}else{
//closed incomplete so update all associated records to close the requested item entirely
current.update();
//And now we'll cancel any other open tasks along with the requested item
if(!gs.nil(current.parent)){
//Close siblings
var otherTasks = new GlideRecord('sc_task');
otherTasks.addEncodedQuery('request_item='+current.request_item+'^stateIN-5,1,2');
otherTasks.query();
while(otherTasks.next()){
otherTasks.state = '4';
otherTasks.update();
}
//Close parent
var ritm = new GlideRecord('sc_req_item');
if(ritm.get(current.parent)){
ritm.state = '4';
ritm.stage = 'Cancelled';
ritm.update();
}
}
}
}
Code like this can be easily retrofitted to provide you with a good template for interacting with users before you save your record.
If for some reason the attached UI Action doesn't work, toggle the "isolate script" field (save it on then off) and it should run just fine.
Have fun.
- 21,477 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I tried this in a scoped app but doesn't work. Same exact code on catalog task record works. Do you know if there is way to make it work for scoped apps?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
It is probably the "window.changeTaskAction" part of the code that is not working in the scope.
You can achieve much of the same behaviour with GlideModal by using a UI Page rather than using "renderWithContent".
By using a UI Page you do not need to be listening to the modal changes inside of the UI Action as your scripts will go inside the UI Page's own client script.
Just remember that you won't have access to the "current" object but you could pass some values into the UI Page using "setPreference". For example pass in the parent sys_id and then your UI Page can perform a GlideRecord query to retrieve the record.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I had the same issue. The Ui Action was not working directly. The solution i found, in my case was modify the way to call the JS function
window.changeTaskAction = function(thisButton, thisAction
by
top.window.changeTaskAction = function(thisButton, thisAction
and all the HTML codes
onclick="window.changeTaskAction(this.
by
onclick="top.window.changeTaskAction(this.
Due a scope security reasons the function has not access to be called as a window object at the client scripts. You have to use TOP
Let me know if that helps
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
It sure did help me. I was using the same script that Peter mentioned at the top of this thread and it worked fine in my PDI, but when I moved it to our regular Dev instance it quit working.
Thx for this.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Is the value of thisAction available to the server side. I'm needing to take the selected value of the dropdown and create a new record in another table using what was selected.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Stan, yes, the server side code could be modified to create new records on-the-fly. Don't forget to take into account the code changes above if you run into problems with the modal button not closing properly.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Peter,
Thx for responding. I actually found a way to get to what I wanted by calling a Script Include using GlideAjax and passing the value of thisAction as a parameter. A single dropdown like in your example was pretty straightforward. Now I have to create one with 2 dropdowns.
I see:
window.changeTaskAction = function(thisButton, thisAction)
thisButton is the button clicked and thisAction is the vale of the dropdown. Can there be more than 1 value in the case of 2 dropdowns?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
As you're introducing more functionality, I'd recommend using event listeners. This will allow you to distinguish between events and the data associated with them. Check out this example
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I have used this glide modal to display a list of records. However the list of records are shown in columns that I don't need really. I need it to display certain columns that I feel are important. When I tried using personalize list icon, it did not work. How can I achieve what I need?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Im trying to repurpose this to work on the incident form and everything seems to be okay with rendering the HTML and modal but none of the buttons are responding.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Try logging to the console within window.changeTaskAction to see what's happening, ie.
console.log('this button and action were undertaken');
console.log(thisButton);
console.log(thisAction);
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Brilliant, thank you Peter!!!!!!!!!!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Peter,
In our instance there is a customization made in UI Action for the visibility of Dialog window with drop down list to opt.
The drop down list within the dialog box (which was made up with the syntax line "var dialog = GlideModal ? GlideModal : GlideDialogWindow;" followed by calling the list) is only accessible to the "admin" role users, other than admin role users can able to see the dialog window but not able to access/opt the drop down list values.
Could you please help me by guiding the resolution for this issue.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @petercawdron,
In our instance there is a customization made in UI Action for the visibility of Dialog window with drop down list to opt.
The drop down list within the dialog box (which was made up with the syntax line "var dialog = GlideModal ? GlideModal : GlideDialogWindow;" followed by calling the list) is only accessible to the "admin" role users, other than admin role users can able to see the dialog window but not able to access/opt the drop down list values.
Could you please help me by guiding the resolution for this issue.