GlideDialogWindow: Advanced Popups Using UI Pages

//GlideDialogWindow: Advanced Popups Using UI Pages

GlideDialogWindow: Advanced Popups Using UI Pages

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 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 ServiceNow. 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 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.

‘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 ServiceNow 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.
By | 2018-07-09T15:00:06+00:00 September 23rd, 2010|Categories: System UI|Tags: , , , , , |43 Comments

About the Author:

Mark has worked in the IT industry since 2002 and with ServiceNow since 2007. He is the founder and creator of SN | Guru and the co-founder of Crossfuze, one of the worlds leading ServiceNow consulting partners. Prior to co-founding Crossfuze, he worked for ServiceNow as a Senior Architect on the Professional Services team. He has personally led dozens of successful implementations encompassing every part of the ServiceNow platform. He is also responsible for designing and developing groundbreaking ServiceNow solutions and best practices in the form of various applications, turnkey solutions, and integrations during his tenure at ServiceNow, Crossfuze and, of course, SN | Guru. These solutions are used today by ServiceNow administrators and consultants alike in hundreds of ServiceNow instances around the world!

43 Comments

  1. Bruno Hildebrando September 27, 2010 at 6:31 am - Reply

    Thanks Mark, i´ve tried and looks great!

  2. Russ Hart September 28, 2010 at 10:03 pm - Reply

    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

    • Mark Stanger September 29, 2010 at 12:04 am - Reply

      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
      }
  3. Russ hart September 28, 2010 at 10:20 pm - Reply

    Also noticed that it works on IE but not Firefox ?

    • Mark Stanger September 29, 2010 at 12:14 am - Reply

      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.

      • mthrash August 1, 2011 at 9:04 am - Reply

        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?

        • Mark Stanger August 1, 2011 at 9:34 am - Reply

          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.

        • Mark Stanger October 6, 2011 at 2:22 pm - Reply

          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"/>
  4. Carl Hensley June 20, 2011 at 2:13 pm - Reply

    Excellent works great thanks!

  5. Jon July 14, 2011 at 5:57 pm - Reply

    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.

    • Mark Stanger July 15, 2011 at 7:33 am - Reply

      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" />
  6. Louwee Guevarra December 19, 2011 at 1:20 pm - Reply

    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.

  7. Ron June 28, 2012 at 10:25 am - Reply

    Mark,

    How can I set the height and width of the dialog box?

  8. Kevin Sandberg July 17, 2012 at 4:58 am - Reply

    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

    • Mark Stanger July 17, 2012 at 6:43 am - Reply

      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

      • Kevin Sandberg July 17, 2012 at 6:48 am - Reply

        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.

        • Mark Stanger July 17, 2012 at 6:51 am - Reply

          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 :).

          • Kevin Sandberg July 17, 2012 at 7:05 am - Reply

            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.

  9. Ron July 27, 2012 at 4:28 pm - Reply

    Mark, is it possible to return a value from the UI Page back to the UI Action?

    • Mark Stanger July 27, 2012 at 4:30 pm - Reply

      Hey Ron, I’m not aware of any way to do that currently.

  10. Slava Savitsky September 5, 2012 at 8:21 am - Reply

    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?

    • Mark Stanger September 5, 2012 at 8:28 am - Reply

      @slava, I’m glad it’s working for you. I’m not sure why making that change would fix things though.

  11. Akshat September 11, 2012 at 10:29 am - Reply

    Hi Mark

    I have tried which you suggested me to do..But unfortunately it’s not working for me..

  12. ND November 4, 2012 at 8:28 pm - Reply

    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

  13. ND November 4, 2012 at 8:35 pm - Reply

    Hi,

    Just found solution :

    gsftSubmit(document.getElementById(‘sysverb_update_and_stay’));

    ND

  14. Jay November 28, 2012 at 3:23 am - Reply

    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

    • Mark Stanger November 29, 2012 at 2:58 pm - Reply

      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.

  15. Amisha Parekh August 5, 2013 at 11:26 am - Reply

    Hi Mark,

    Is it possible to have Glidewindow to display all related list of the form?

    Thanks & Regards,
    Amisha Parekh

  16. Matt September 27, 2013 at 2:11 pm - Reply

    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.

    • Mark Stanger September 27, 2013 at 2:42 pm - Reply

      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.

  17. Adam February 19, 2014 at 1:11 pm - Reply

    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!

  18. Michael Speirs August 26, 2015 at 2:31 pm - Reply

    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);
    }

  19. William December 21, 2015 at 9:17 am - Reply

    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!

  20. Nicole McCray July 11, 2016 at 8:41 am - Reply

    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.

  21. Roan August 23, 2016 at 4:35 am - Reply

    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!

  22. Adam December 2, 2016 at 7:33 am - Reply

    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?

    • Mark Stanger December 2, 2016 at 7:52 am - Reply

      ServiceNow doesn’t support this type of thing in the mobile interface.

  23. Manish June 27, 2017 at 1:13 pm - Reply

    Can i add an attachment link in the dialog window so that the users can add attachment in window itself?

    • Mila Morales September 21, 2017 at 9:37 am - Reply

      You can use this script:

      var sysId = g_form.getUniqueValue(); // sysId of the record to which attachment is to be added
      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();

Leave A Comment