O

ne problem I’ve seen a few times is the need to create a new record on the fly in order to populate it into a reference field. This problem recently came up for me with a client I’m working with so I decided to come up with a good solution. An example scenario would be a technician filling out an incident record for a user that doesn’t yet exist in the system. At first glance, the solution seems simple enough…simply navigate to the user form and create the new user, then create your incident record. While that can be done, it’s not always so simple. What if the technician has just spent several minutes filling out the incident and then realizes the caller doesn’t exist? The user would then have to navigate away from that incident record and lose all of the changes, or open an entirely new browser window to create the user and then return and populate the field.

Fortunately, there is a better way if you know how to leverage UI Macros and GlideDialogWindow QuickForms. This article shows a solution that you can use for any ‘sys_user’ reference field in your system. It can also be easily modified and applied to other reference fields as well.

GlideDialogWindow-Add User

The first step in this solution is to create a new UI Macro that can be associated to the reference field(s) that you want to be able to create new records from. The macro I’ve created here is very loosely based on an out-of-box macro, but also has three very important differences.

  1. The first difference is that it uses standard ‘A’ and ‘IMG’ html tags to display the macro icon rather than the ‘g:reference_decoration’ tag that is normally used for reference field macros. The reason for this is that we need the macro to always be visible…especially if the reference field doesn’t have anything in it. By design, the ‘g:reference_decoration’ tag only shows the macro if something is populated in the reference field.
  2. The other change is what the ‘onClick’ event (the ‘addEditUserPop’ function) does when the macro icon is clicked. It opens a GlideDialogWindow quickform to display either a new record window (to add a new record if the field is empty when the macro is clicked) or an edit window to edit the record (if the field is populated when the macro is clicked). Check this article out if you need more information about how GlideDialogWindow quickforms work.
  3. Lastly, the callback function (the ‘setUserField’ function) gets called after the dialog is submitted and populates the reference field with the newly-added or edited record.

You can set up the UI Macro like this…

‘add_edit_user’ UI Macro
Name: add_edit_user
Description:
Show add/edit user macro icon on a reference field
Activate by:
– Setting the active field in this macro to true
– Adding the attribute to a dictionary field: ref_contributions=add_edit_user
XML:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
   <g:evaluate var="jvar_guid" expression="gs.generateGUID(this);" />
   <j:set var="jvar_n" value="add_edit_user_${jvar_guid}:${ref}"/>
   <a id="${jvar_n}" onclick="addEditUserPop('${ref}')">
      <img border="0" src="images/icons/user_profile.gifx" title="${gs.getMessage('Add/Edit User')}" alt="${gs.getMessage('Add/Edit User')}"/>
   </a>

   <script>
      //OnClick function for UI macro
      function addEditUserPop(reference){
         var s = reference.split('.');
         var referenceField = s[1];
         var v = g_form.getValue(referenceField);

         //If user field is empty then pop open an 'Add User' dialog
         if(v == ''){
            var dialog = new GlideDialogForm('Add User', 'sys_user', setUserField);
            dialog.setSysID('-1'); //Pass in -1 to create a new record
         }
         //Else pop open an 'Edit User' dialog for the populated user record
         else{
            var dialog = new GlideDialogForm('Edit User', 'sys_user', setUserField);
            dialog.setSysID(v); //Pass in reference sys_id to edit record
         }
         dialog.addParm('sysparm_view', 'default'); //Specify a form view
         dialog.addParm('sysparm_form_only', 'true'); //Remove related lists
         dialog.render(); //Open the dialog

         //Callback function executed from dialog submit
         function setUserField(action, sys_id, table, displayValue){
            //Set the user field with the popup user
            g_form.setValue(referenceField, sys_id);
         }
      }
   </script>
</j:jelly>

XML (Fuji version):

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
   <g:evaluate var="jvar_is_itil" expression="gs.hasRole('itil')" />
   <j:if test="${jvar_is_itil == true }">
      <g:evaluate var="jvar_guid" expression="gs.generateGUID(this);" />
      <j:set var="jvar_n" value="cf_add_edit_user_${jvar_guid}:${ref}"/>
      <a>
          <span id="${jvar_n}" onclick="addEditUserPop('${ref}')"
          class="btn btn-default icon-add-circle"
          title="${gs.getMessage('Add User')}"
          alt="${gs.getMessage('Add User')}">
          </span>
      </a>

      <script>
         //OnClick function for UI macro
         function addEditUserPop(reference){
            var s = reference.split('.');
            var referenceField = s[1];
            var v = g_form.getValue(referenceField);

            //If user field is empty then pop open an 'Add User' dialog
            if(v == ''){
               var dialog = new GlideDialogForm('Add User', 'sys_user', setUserField);
               dialog.setSysID('-1'); //Pass in -1 to create a new record
            }

            //Else pop open an 'Edit User' dialog for the populated user record
            else{
               var dialog = new GlideDialogForm('Edit User', 'sys_user', setUserField);
               dialog.setSysID(v); //Pass in reference sys_id to edit record
            }
            dialog.addParm('sysparm_view', 'add_user'); //Specify a form view
            dialog.addParm('sysparm_form_only', 'true'); //Remove related lists
            dialog.render(); //Open the dialog

            //Callback function executed from dialog submit
            function setUserField(action, sys_id, table, displayValue){
               //Set the user field with the popup user
               g_form.setValue(referenceField, sys_id);
            }
         }
      </script>
   </j:if>
</j:jelly>

Once you’ve set up the UI Macro, you need to add the appropriate attribute to the reference field so that the macro will be displayed. In order to do that, you simply need to personalize the dictionary for your reference field and add the ‘ref_contributions=add_edit_user‘ attribute to the ‘Attributes’ field on the dictionary. If you have multiple ‘ref_contributions’ attributes, they should be separated by a semicolon and this macro will look best if it is the first macro listed for the field.

That’s it! Here are a few screenshots of the finished product!

Add/Edit User UI Macro
AddEditUser-Macro

Add User Dialog Window
GlideDialogWindow-Add User

Edit User Dialog Window
GlideDialogWindow-Edit User

Reference field populated with new user