GlideDialogForm with Callback ‐ Populating Reference Fields - ben-vargas/servicenow-wiki GitHub Wiki

This article explains how to use the GlideDialogForm with a callback function to create or edit records from a popup window and automatically update a reference field on the originating form. This method allows users to quickly create or modify records without leaving the current form and provides a seamless user experience.

The Problem:

ServiceNow reference fields often allow users to select existing records. However, when a required record doesn't exist, users typically need to navigate away from their current form, create the record in a new tab or window, and then return to select it. This can interrupt workflow and be inefficient.

Use Case:

A common scenario is when a user needs to select a "Caller" on a form, but the caller's user record does not yet exist in the system. Using the standard lookup functionality, the user would need to open the user record list, create the record, and return to the original form. This solution aims to allow users to create a new user record directly from a popup without leaving their current form.

The Solution:

The GlideDialogForm class in ServiceNow provides a way to display a form within a popup. It also offers a callback mechanism, allowing you to pass data back to the originating form after the popup is closed. This solution leverages that functionality, using a custom icon next to a reference field to open a new user form as a GlideDialogForm. When the user saves the new record, the original field is automatically updated with the new record’s sys_id.

Implementation Steps:

This solution comprises the following components:

  1. Client Script: This script adds an icon next to the reference field, which when clicked, opens a popup containing the form specified in the script. This script also handles passing the sys_id to populate the form with a pre-existing record if it exists.
  2. Callback Function: The callback function, dothis in the example, is executed after the popup form is submitted or cancelled. It receives the action, sys_id, table, and display value as parameters from the popup and sets the reference field's value with the created sys_id.
  3. CSS Considerations: The client script can only add the HTML for the icon, but CSS is required to prevent the icon from looking out of place.

Code Snippets:

Here is the enhanced Client Script code:

function onLoad() {
    var field = 'caller_id'; // The reference field to target
    var table = g_form.getTableName();
    var edit = false; // Set to true to show the icon even if the field is populated, allowing edits
    var lookupfield = 'lookup.' + table + '.' + field;
    var userIcon = $(lookupfield);
    var fieldValue = g_form.getValue(field);
    var fieldId = '';

    if (userIcon) {
        if (edit == true && fieldValue !== '') {
            fieldId = fieldValue;
        }
        if(fieldValue == '' || edit == true) {
          userIcon.insert({
              after: '<a id="AddUserPopup"><img width="16" height="16" border="0" src="images/icons/user_licensed.gif" title="Add/Edit User"></a>'
          });

            var userPop = $('AddUserPopup');
            if(userPop) {
              userPop.observe('click', function() {
                userPopup(fieldId);
                });
            }
        }
    }

    function userPopup(fieldId) {
        var dialog = new GlideDialogForm('User Management', 'sys_user', dothis);
        dialog.setTitle("User Management");
        dialog.setSysID(fieldId); // pass in sys_id to edit existing record
        dialog.addParm('sysparm_view', 'default'); // Specify the view to display
        dialog.addParm('sysparm_form_only', 'true'); // Display only the form, no headers, tabs, etc.
        dialog.render();
    }

    function dothis(action, sys_id, table, displayValue) {
      // action can be either 'save', 'update' or 'close'
      if (sys_id){
           g_form.setValue(field, sys_id);
      }
    }
}

CSS:

It is recommended to add CSS to avoid the icon looking out of place. Here are some sample settings that can be applied via a theme or the system UI.

#AddUserPopup {
  vertical-align: middle;
  margin-left: 4px;
  text-decoration: none;
}

Explanation:

  1. onLoad() Function:
    • Gets the field name from the field variable and determines if the edit flag is set.
    • Builds the lookup field id string and uses this to select the proper location to insert the icon on the form.
    • Retrieves the current value from the field so it can be used later when editing a record.
    • Inserts an anchor tag with a user_licensed.gif icon next to the reference field.
    • An observer is added to the click event on the created icon. When clicked, it calls the userPopup() function with the field's sys_id.
  2. userPopup() Function:
    • Creates a new GlideDialogForm object, specifying the title as 'User Management' and the table as sys_user (the user table).
    • Sets the record's sys_id if one exists.
    • Specifies the view to display.
    • Displays only the form by setting sysparm_form_only to true.
    • Renders the popup window.
  3. dothis() Function (Callback):
    • The callback function, dothis, retrieves the returned sys_id and sets the value of the specified field on the main form.
    • The action parameter can be used to execute conditional logic depending on if the user saved the record in the dialog.

How to Implement:

  1. Create Client Script:
    • Navigate to System Definition > Client Scripts.
    • Create a new Client Script, selecting the appropriate table you would like to apply this functionality to.
    • Set the type to onLoad.
    • Copy the script from the "Code Snippets" section above into the script field.
    • Adjust the field variable to match the reference field you are targeting on the form.
    • Adjust the edit flag if necessary.
  2. CSS Implementation:
    • Add the CSS code provided to the theme or the system UI stylesheet, as appropriate.
  3. Test:
    • Open the form and you should see an icon next to your reference field.
    • Clicking the icon should display the popup dialog.
    • Creating a new record or editing an existing record should populate the field on the originating form.

Best Practices:

  • Configuration: Make sure to configure the field, table, view, and edit variables to match your specific needs.
  • Error Handling: While this example does not have error handling, consider adding error handling in your client script, especially for production environments.
  • Code Comments: Comments are crucial for understanding and maintaining code; always use comments when appropriate.
  • Reusability: The main logic can be used in other reference fields by simply changing the defined variables.
  • Asynchronous Behavior: Be aware of potential asynchronous behavior and test the script thoroughly to ensure it behaves as expected.

Conclusion:

By using a GlideDialogForm with a callback function, you can enhance the user experience by allowing them to create new records without leaving their current form. This solution is efficient, user-friendly, and can be adapted to various use cases in your ServiceNow environment. Remember to test all changes thoroughly in a non-production instance before implementing them in production.