Custom Glide Modal Dialog Boxes
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.
https://www.servicenow.com/community/now-platform-articles/custom-glide-modal-dialog-boxes/ta-p/2321142