SATURDAY, MAY 19, 2012

GlideDialogWindow: Advanced Popups Using UI Pages

T

his article is the 3rd in a series of posts explaining the use of ‘GlideDialog’ in Service-now. If you want to see all of the articles I’ve written about GlideDialogWindow and popups in Service-now 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 only warning I’ll give here is this: While it’s very easy to pop open a dialog window using this method, the real work happens in the UI Page contained in the dialog. The purpose of this post is not to explain the complexities of creating your own UI Pages in Service-now. Until I get a chance to write about those, the best recommendation I can give you would be to take a look at the UI Pages you’ll find out-of-box in your system.


The example I’ll use here is based off one that a Service-now 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.

‘Comments Dialog’ UI Action
Name: Comments Dialog
Table: Incident
Action name: comments_dialog
Form Button: True
Client: True
Onclick: commentsDialog()
Script:

function commentsDialog() {
   //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.

‘task_comments_dialog’ UI Page
HTML

<g:ui_form>
  <!-- Get values from dialog preferences passed in -->
  <g:evaluate var="jvar_short_text"
    expression="RP.getWindowProperties().get('short_text')" />
  <g:evaluate var="jvar_comments_text"
    expression="RP.getWindowProperties().get('comments_text')" />
   <!-- Set up form fields and labels -->
   <table width="100%">
     <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) -->
         <g:ui_multiline_input_field name="dial_comments" id="dial_comments" label="Additional comments" value="${jvar_comments_text}" mandatory="true" />
       </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-->
           <g:dialog_buttons_ok_cancel ok="return validateComments()"ok_type="button" cancel_type="button" />
        </td>
     </tr>
  </table>
</g:ui_form>

Client script

function validateComments() {
   //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
}
If you’re interested in learning more about how to use this method I highly recommend taking a look at a great example that you can find right in your Service-now instance. The ‘task_assignment_group_choose_by_person’ UI Macro can be added to the ‘assignment_group’ field on any task form by adding the ‘ref_contributions=task_assignment_group_choose_by_person’ attribute to the dictionary entry for that field. The UI Macro shows up as an icon that displays a GlideDialogWindow containing the contents of the ‘task_assignment_group_dialog’ UI Page when it is clicked. The UI Page lets the user search for and select an assignment group to populate on the form.

Comments

Posted On
Sep 27, 2010
Posted By
Bruno Hildebrando

Thanks Mark, i´ve tried and looks great!

Posted On
Sep 28, 2010
Posted By
Russ Hart

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

Posted On
Sep 29, 2010
Posted By
Mark Stanger

The clues to answer this question are contained in this section of the UI Page…

<!-- 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
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…

<!-- 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
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…

function processCancel(){
   GlideDialogWindow.get().destroy(); //Close the dialog window
   reloadWindow(window); //Refresh the form
}
Posted On
Sep 28, 2010
Posted By
Russ hart

Also noticed that it works on IE but not Firefox ?

Posted On
Sep 29, 2010
Posted By
Mark Stanger

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.

Posted On
Aug 01, 2011
Posted By
mthrash

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?

Posted On
Aug 01, 2011
Posted By
Mark Stanger

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.

Posted On
Oct 06, 2011
Posted By
Mark Stanger

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…

<g:dialog_buttons_ok_cancel ok="return termsOK()" cancel="termsCancel()" ok_type="button" cancel_type="button"/>
Posted On
Jun 20, 2011
Posted By
Carl Hensley

Excellent works great thanks!

Posted On
Jul 14, 2011
Posted By
Jon

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.

Posted On
Jul 15, 2011
Posted By
Mark Stanger

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…

<g:ui_choicelist name="closecode" table="incident" field="close_code" />
Posted On
Dec 19, 2011
Posted By
Louwee Guevarra

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.

Posted On
Dec 19, 2011
Posted By
Mark Stanger

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.
http://www.servicenowguru.com/system-definition/login-terms-conditions-dialog/

Leave a Reply


Notify me of followup comments via e-mail. You can also subscribe without commenting.

Latest Comments

  • Jim Coyne: I’m not sure exactly what you are looking for, but can you use “window.location” in your...
  • Ian: Might want to check the single quotes around ITIL in the condition line, they gave an error for me until I...
  • Mark Stanger: That’s correct. This returns instance URLs. I don’t have an equivalent currently that...
  • ND: Hi Mark, This is very useful information. I am looking for similar method to find URL of a site created by us. We...