This article is the 3rd in a series of posts explaining the use of ‘GlideDialog’ in ServiceNow. If you want to see all of the articles I’ve written about GlideDialogWindow and popups in ServiceNow just use the tags at the bottom of this article.
In this article I’ll show you how you can use GlideDialogWindow to pop open a dialog containing any custom UI Page information you want. I’ll also show how you can pass information into those dialogs, and how you can return information from those dialogs back to the standard form that initiated the dialog. These dialogs can be initiated from any place where you can use client scripts…client scripts, UI Macros, UI Actions, etc.
The example I’ll use here is based off one that a ServiceNow developer wrote as an example. It’s not very fancy, but it’s simple enough to show how things work without adding a bunch of confusing elements. It simply opens a dialog with information populated from the form, and returns information from the dialog to the form.
The first piece of this solution is to set up some mechanism to trigger your GlideDialogWindow. For this example I’ve chosen to use a UI Action button. Here are the details of the button. The comments in the script explain how to initialize the dialog and pass parameters on to your UI Page to populate information there.
Name: Comments Dialog
Table: Incident
Action name: comments_dialog
Form Button: True
Client: True
Onclick: commentsDialog()
Script:
//Get the values to pass into the dialog
var comments_text = g_form.getValue("comments");
var short_text = g_form.getValue("short_description");//Initialize and open the Dialog Window
var dialog = new GlideDialogWindow("task_comments_dialog"); //Render the dialog containing the UI Page 'task_comments_dialog'
dialog.setTitle("Add Task Comments"); //Set the dialog title
dialog.setPreference("comments_text", comments_text); //Pass in comments for use in the dialog
dialog.setPreference("short_text", short_text); //Pass in short description for use in the dialog
dialog.render(); //Open the dialog
}
Once you have your UI Action set up to trigger the dialog, you need to make sure that you have the correctly-named UI Page to display in the dialog. In the script above, we used ‘var dialog = new GlideDialogWindow(“task_comments_dialog”);’ to initialize a GlideDialogWindow and point to the ‘task_comments_dialog’ UI Page. Here’s what that page looks like. The comments in the HTML below explain each piece of the UI Page. The client script portion of the UI Page is used to validate the input on submission of the dialog form. If validation passes, the value of the ‘Comments’ field on the dialog is passed to the ‘Comments’ field on the original form.
HTML
<!-- Set up form fields and labels -->
<table width="100%">
<tbody>
<tr id="description_row" valign="top">
<td colspan="2"><!-- Short description value used as a label -->
${jvar_short_text}</td>
</tr>
<tr>
<td><!-- Comments text field (Contains comments from originating record as a default) --></td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr id="dialog_buttons">
<td colspan="2" align="right"><!-- Pull in 'dialog_buttons_ok_cancel' UI Macro for submit/cancel buttons. 'ok' option will call the 'validateComments' Client script function from the UI Page--></td>
</tr>
</tbody>
</table>
Client script
//Gets called if the 'OK' dialog button is clicked
//Make sure dialog comments are not empty
var comments = gel("dial_comments").value;
comments = trim(comments);
if (comments == "") {
//If comments are empty stop submission
alert("Please provide comments to submit the dialog.");
return false;
}
//If comments are not empty do this...
GlideDialogWindow.get().destroy(); //Close the dialog window
g_form.setValue("comments", comments); //Set the 'Comments' field with comments in the dialog
}
Thanks Mark, i´ve tried and looks great!
Hi Mark,
Using this and it’s working well. Can you tell me how to apply an action (e.g. reload form) if the user presses the ‘cancel’ button on the dialog box ?
Thanks
The clues to answer this question are contained in this section of the UI Page…
'ok' option will call the 'validateComments' Client script function from the UI Page
which works like an 'onSubmit' for the dialog-->
<g:dialog_buttons_ok_cancel ok='return validateComments()'/>
The buttons are controlled by a separate macro. You don’t need to modify that macro, but you can look at it to see what its behavior is. You should be able to close the dialog and refresh the form by making a couple of modifications…
1) Change the section of UI Page code above to look like this…
'ok' option will call the 'validateComments' Client script function from the UI Page
which works like an 'onSubmit' for the dialog-->
<g:dialog_buttons_ok_cancel ok='return validateComments()' cancel='processCancel()' cancel_type='button'/>
This will override the ‘cancel’ action with a custom function that you can specify.
2) You can add your ‘processCancel()’ function to the ‘Client script’ field in the UI Page (triggered by the code you modified above). A function to close the dialog and refresh the underlying page would look like this…
GlideDialogWindow.get().destroy(); //Close the dialog window
reloadWindow(window); //Refresh the form
}
Also noticed that it works on IE but not Firefox ?
I’ve confirmed that this works correctly in Firefox on both PC and Mac. I would suggest testing this same setup on the Service-now demo instance to see if you get different results. My guess is that you’ve got a conflict with some other client scripts in your system.
Mark, thank you so much for this we have it working very well in Firefox and IE. Chrome seems to have an issue with this though. I have tried it in three different instances including SN demo and get “window not found” error after I submit. Any thoughts?
Looks like a bug to me but I haven’t had much of a chance to troubleshoot it either. I’ll let you know if I figure anything out that works in Chrome as well.
I just found a fix for this problem. The UI page above uses dialog buttons that need to have a special setting so that the button acts as a regular button instead of trying to perform a form submission…and redirecting the user. Take a look at your ‘dialog_buttons’ line in your UI page and make sure that it has both an ‘ok_type’ and a ‘cancel_type’ of ‘button’ as shown here…
Excellent works great thanks!
Instead of a comments field, I’m trying to allow setting of “close code” in a popup, and other fields in the future, like Assigned To.
The place where I’m stuck is how to represent the Close code or Assigned To field in the UI Page HTML. These aren’t just text fields, but text field that has choices (Dropdown) and Lookup fields. How can these be represented in the UI Page HTML to preserve their function, if even possible?
Thanks everyone.
Good question. I think the first thing I would try is the ‘QuickForm’ functionality. That would be much simpler to setup and maintain. If you need to add specific elements to a UI page, you have access to several pre-built field types in the UI macros table. These UI macros all start with the ‘ui_’ prefix in their name. The ‘ui_choicelist’ UI macro will allow you to add a choice list to a UI page. If you wanted to add the close code field from the incident form to your page, you could use code like this…
When user click Agree, does the feature keep track of the users agreeing to the terms and condition that can be used to run a report.
If you’re referring to the Terms and Conditions update set described here, then the answer is yes…otherwise you would need to add the logging.
https://servicenowguru.wpengine.com/system-definition/login-terms-conditions-dialog/
Mark,
How can I set the height and width of the dialog box?
You should be able to use ‘setSize’ as shown here.
https://servicenowguru.wpengine.com/system-ui/glidedialogwindow-terms-conditions-acceptance-page/
Hi Mark,
Is it possible to pull through the display value of a reference field using this technique? I do not want the full field just the content of the reference field in a similar way to the short description being pulled through on this example.
I am trying to use the techniques described here to produce a UI Page with a finance invoice print out and this would help me achieve what I am looking to do.
Thanks,
Kevin
Sure, really the dialog will be the same, you just need to get the display value of the reference field. You can do that like this…
g_form.getDisplayBox(‘caller_id’).value
Thanks for your quick response – I have actually tried what you have suggested – and for some reason I am getting ‘null’ returned. So close – but yet so far.
Thanks.
It might be an issue with the field being read only then. Client-side methods don’t work well on read only fields. You’ll also need to have the field on the form to get at it easily from the client. As an alternative you could do an asynchronous GlideRecord call to try to get the data. It could get pretty involved depending on what you need to get to. Bottom line is that the dialog works the same way either way. Just have to get to the data :).
Thanks Mark – I had a feeling this was going to be a bit more complicated than I first thought – The UI Page I am trying to create is basically a summary of a request. It needs to pull through Approvers and details of the Requested Items. Got a feeling Im going to be scratching my head alot over the next couple of weeks.
Thanks again.
Mark, is it possible to return a value from the UI Page back to the UI Action?
Hey Ron, I’m not aware of any way to do that currently.
Hi Mark,
This is really cool stuff! I am currently trying to use this technique to enhance functionality for submission of feedbacks to KB articles.
For some reason, the processing script I put in UI page was not executed until I replaced ok_type=”button” with ok_id=”ok_button” in tag. The client script part worked fine anyway though. Is there any explanation for this?
@slava, I’m glad it’s working for you. I’m not sure why making that change would fix things though.
Hi Mark
I have tried which you suggested me to do..But unfortunately it’s not working for me..
Hi Mark,
Gr8 article..
I have one further requirement in it. Once user put additional information and click ok, is is possible to save form automatically rather than manually updating the record.
ND
Hi,
Just found solution :
gsftSubmit(document.getElementById(‘sysverb_update_and_stay’));
ND
Hi Mark,
Great Article..
I am using the above stuff for “Related List”.
My requirement is – whenever user “Rejects” approval from the related list, he should be shown UI Page asking for Comments. Further on clicking ok the comments should appear in the related list comments field and approval should be changed to Approved state.
Problem I am facing is that, I am not able to get control of the fields in the related list. How to copy comments and update the related list ?
Any suggestions ?
Thanks
Jay
Hi Jay,
That’s going to be fairly complex. I usually just remove the list actions and have the user open the form in order to avoid that complexity. I don’t have any other specific pointers, but you might try asking this on the SN forums and see if anybody there has something you could use.
Hi Mark,
Is it possible to have Glidewindow to display all related list of the form?
Thanks & Regards,
Amisha Parekh
Hi Mark,
Great article as always. Are you aware of a way to pass the value of the ui_page back to ui_action and force the ui_action wait for the response of the glide dialog. I am trying to replicate the functionality of JavaScript prompt message, but in a custom dialog with a drop down.
Thanks in advance for your time.
Thanks Matt. I’m sure there’s a way, but I don’t know what it would be off the top of my head. Please post back here if you find a solution.
Hi,
This was very helpful to me, although I was wondering if you have tried, or have been able to use the value in a processing script? I’m trying to create a change request using a processing script that grabs values from this UI page, but for some reason I keep getting a %variablename% is undefined when attempting to get at the value in that field type.
Thanks!
I haven’t tried that before unfortunately. I would guess it’s possible, but would probably have to dig a bit to figure it out. You might try on the SN community to see if anybody there has dealt with something similar before.
Yes, it is possible to use the values in the processing script. It is described here: http://wiki.servicenow.com/index.php?title=UI_Pages#Using_a_Processing_Script
You can define a callback function with parameters in the UI Action and call it from the client script portion of the UI Page.
UI Action:
…
…
dialog.render(); //Open the dialog
}
function dialogCallback(value) {
//…use value
}
UI Page client script:
…
…
var value = …;
dialogCallback(value);
}
Mi Mark, how can I adapt this to write to the work_notes instead of the comments field? I have tried changing everything from comments to work_notes, but it’s still not working. Any help would be great!
I have 8 fields that currently exist on my form, that need to be replicated in new rows when the ‘Add another course’ button is clicked (I also need this button to appear at the bottom of these new rows to be clicked again if needed).
I have a variable of type ‘UI page’ called ‘sc_button’.
I am looking for a script that I can specify as the ‘default value’ that will produce these replicated fields when button is clicked.
My issue in using the GlideDialogWindow was that it opens a new window tab instead of a dialog. Original issue was, using a popupOpenStandard, the dialog was opened but when click outside the dialog, the box was automatically closed. What i need is the popup should retain open until the close button is clicked.
This is why i used GlideDialogWindow but the result should be a dialog box not a new tab.
Any thoughts?
Your help would be greatly appreciated.
Thanks!
Hi there – many thanks, works great however how can I get this working on the mobile app? I created the same UI action, the button appears but does nothing?
Any ideas?
ServiceNow doesn’t support this type of thing in the mobile interface.
Can i add an attachment link in the dialog window so that the users can add attachment in window itself?
You can use this script:
var tableName = g_form.getTableName(); // table name give as per your table name
var dialog = new GlideDialogWindow("attachment");
dialog.setTitle("Add Attachment");
dialog.setPreference("target_sys_id",sysId);
dialog.setPreference("target_table",tableName);
dialog.render();