UI macros Archives - ServiceNow Guru https://servicenowguru.com/tag/ui-macros/ ServiceNow Consulting Scripting Administration Development Tue, 28 May 2024 20:33:14 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 https://servicenowguru.com/wp-content/uploads/2024/05/cropped-SNGuru-Icon-32x32.png UI macros Archives - ServiceNow Guru https://servicenowguru.com/tag/ui-macros/ 32 32 GlideDialogWindow: Advanced Popups Using UI Pages https://servicenowguru.com/system-ui/glidedialogwindow-advanced-popups-ui-pages/ https://servicenowguru.com/system-ui/glidedialogwindow-advanced-popups-ui-pages/#comments Wed, 23 Jun 2021 14:00:25 +0000 https://servicenowguru.wpengine.com/?p=2060 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

The post GlideDialogWindow: Advanced Popups Using UI Pages appeared first on ServiceNow Guru.

]]>
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 on 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

<table width="100%">
<tbody>
<tr id="description_row" valign="top">
<td colspan="2">${jvar_short_text}</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</tbody>
</table>

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.

The post GlideDialogWindow: Advanced Popups Using UI Pages appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-ui/glidedialogwindow-advanced-popups-ui-pages/feed/ 47
Open Google Map from a Location Record https://servicenowguru.com/ui-actions-system-ui/open-google-map-location-record/ https://servicenowguru.com/ui-actions-system-ui/open-google-map-location-record/#comments Wed, 15 May 2013 13:56:12 +0000 https://servicenowguru.wpengine.com/?p=4910 This week I’m blogging from Knowledge13 in Las Vegas! So far it’s been a fantastic conference with lots of great content and it’s been fun to meet with so many people interested in improving their ServiceNow implementation. I’m really looking forward to the Fred Luddy keynote this morning. Jacob Andersen and I are here representing

The post Open Google Map from a Location Record appeared first on ServiceNow Guru.

]]>
This week I’m blogging from Knowledge13 in Las Vegas! So far it’s been a fantastic conference with lots of great content and it’s been fun to meet with so many people interested in improving their ServiceNow implementation. I’m really looking forward to the Fred Luddy keynote this morning. Jacob Andersen and I are here representing our ServiceNow consulting company, Crossfuze Solutions and would love to talk with any of you who could benefit from working with the most experienced ServiceNow implementation and integration consultants in the industry. Stop by the BDNA booth (Booth 1216) during any of the expo times to visit with us and see some of our world-class Incident, Problem, Knowledge, Change, Catalog, CMS, and Asset Management solutions! I’ll also be participating in a sold out panel presentation at 1:40 today where we’ll discuss the importance of data quality in a ServiceNow implementation.

Okay, enough of the high-pressure sales pitch :). This morning I saw a post on the ServiceNow community asking how to display a google map based on a ServiceNow location record. I think this is a fantastic idea and I decided to see if I could come up with a couple of solutions for it this morning. In this post I’ll show you how you can set up a UI Action or UI Macro link to pop open a Google Map window based on any location record in your ServiceNow instance!

Location Google Map UI Macro

The simplest way to set up a Google Map link in ServiceNow is to use a client-side UI Action to construct the URL and pop open a new window. Google Map URLs follow a basic convention that can include the street address or latitude/longitude coordinates of the location you want to display like this…

http://maps.google.com/?q=1200 Pennsylvania Ave SE, Washington, District of Columbia, 20003

Here’s the code and configuration for a UI Action…

‘Open Google Map’ UI Action
Name: Open Google Map
Table: Location [cmn_location] Action name: open_google_map
Show insert: false
Client: true
Form link/List context menu: true
OnClick: openGoogleMap()
Condition: (!current.street.nil() && !current.city.nil()) || (!current.latitude.nil() && !current.longitude.nil())
Comments: Shows a google map icon on a location field if the location has a street and city listed.Crossfuze Solutions
www.crossfuze.com
Script:

//Pop open google maps window of location specified
//URL should follow this format...http://maps.google.com/?q=1200 Pennsylvania Ave SE, Washington, District of Columbia, 20003

function openGoogleMap() {
//Retrieve the 'Location' record
var sysId = typeof rowSysId == 'undefined' ? gel('sys_uniqueValue').value : rowSysId;
var gr = new GlideRecord('cmn_location');
gr.get(sysId);

//Create and display the Map URL
var mapURL = "http://maps.google.com/?q=";
//Try location and city
if(gr.street && gr.city){
mapURL = mapURL + gr.street + ',' + gr.city + ',' + gr.state + ',' + gr.zip + ',' + gr.country;
}
//Else try latitude and longitude
else if(gr.latitude && gr.longitude){
mapURL = mapURL + gr.latitude + ',' + gr.longitude;
}
//Strip '#' symbols to avoid encoding errors
mapURL = mapURL.replace(/#/g, "");
window.open(mapURL);
}

Once the UI Action is created, you should be able to right-click a location record from a list or click the ‘Open Google Map’ link as shown here…

Location Google Map UI Action

While it’s nice to be able to open a map from a location record, it’s probably even more useful to be able to open a map directly from a referenced location record. The code for the UI Macro is a bit more complex, but once created it’s very simple to include for any reference field in your system by personalizing the dictionary entry for the location reference field (or the ‘cmn_location’ table dictionary entry if you want to include the option on every location field in your system). You can create the UI Macro using these settings.

‘open_google_map’ UI Macro
Name: open_google_map
Description:Shows a google map icon on a location field if the location has a street and city listed.
Activate by adding the attribute: ref_contributions=open_google_map to a location reference fieldCrossfuze Solutions
www.crossfuze.com

Script:

<!--?xml version="1.0" encoding="utf-8" ?-->



var id = __ref__.getSysIdValue();
if (id == null)
"none";
else {
var loc = new GlideRecord('cmn_location');
loc.get(id);
if ((!loc.street.nil() $[AND] !loc.city.nil()) || (!loc.latitude.nil() $[AND] !loc.longitude.nil()))
"";
else
"none";
}

<a id="${jvar_n}" style="display: $[jvar_show_google_map_display];" title="${gs.getMessage('Open a Google Map for this location')}" name="${jvar_n}"></a>
<img src="https://servicenowguru.com/wp-content/uploads/2024/02/favicon2." width="16" height="16" border="0" />

<script>
      needsRefreshLoc = false;
      function onChange_location_show_google_map(element, original, changed, loading) {
         var s = '${ref}'.split('.');
         var referenceField = s[1];
         if (needsRefreshLoc == false) {
            needsRefreshLoc = true;
            return;
         }
         if (changed.length == 0) {
            $('${jvar_n}').hide();
            return;
         }
         var locRec = g_form.getReference(referenceField, locationGoogleMapReturn);
      }
      
      function locationGoogleMapReturn(locRec) {
         var e = $('${jvar_n}');
         if ((locRec.street $[AND] locRec.city) || (locRec.latitude $[AND] locRec.longitude))
            e.show();
         else
            e.hide();
      }
      
      //Event.observe(g_form.getControl(${ref}.split('.')[1]), 'change', onChange_cmn_location_show_google_map);
      var l = new GlideEventHandler('onChange_location_show_google_map', onChange_location_show_google_map, '${ref}');
      g_event_handlers.push(l);

      //Pop open google maps window of location specified
      //URL should follow this format...http://maps.google.com/?q=1200 Pennsylvania Ave SE, Washington, District of Columbia, 20003

      function openGoogleMap(reference) {
         var s = reference.split('.');
         var referenceField = reference.substring(s[0].length+1);
         var sysId = g_form.getValue(referenceField);
         //Retrieve the 'Location' record
         var gr = new GlideRecord('cmn_location');
         gr.get(sysId);

         //Create and display the Map URL
         var mapURL = "http://maps.google.com/?q=";
         //Try location and city
         if(gr.street $[AND] gr.city){
            mapURL = mapURL + gr.street + ',' + gr.city + ',' + gr.state + ',' + gr.zip + ',' + gr.country;
         }
         //Else try latitude and longitude
         else if(gr.latitude $[AND] gr.longitude){
            mapURL = mapURL + gr.latitude + ',' + gr.longitude;
         }
	 //Strip '#' symbols to avoid encoding errors
	 mapURL = mapURL.replace(/#/g, "");
         window.open(mapURL);
      }
   </script>

Once the UI Macro has been created and the ‘ref_contributions’ attribute added to the reference field or table dictionary, you should see a google map icon displayed next to your location field whenever a location is referenced that includes address or latitude/longitude details.

Location Google Map UI Macro

The post Open Google Map from a Location Record appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-actions-system-ui/open-google-map-location-record/feed/ 26
‘Add Me’ UI macro for User and Group Fields https://servicenowguru.com/ui-macros/add-me-ui-macro-user-group-fields/ https://servicenowguru.com/ui-macros/add-me-ui-macro-user-group-fields/#comments Fri, 23 Mar 2012 15:20:13 +0000 https://servicenowguru.wpengine.com/?p=4341 This post comes in response to a question I saw this morning on the ServiceNow forum. The request was to be able to create ‘Add me’ icons for user and group fields that would act the same way as the ‘Add me’ field on list fields. This post shows you how! This functionality can be

The post ‘Add Me’ UI macro for User and Group Fields appeared first on ServiceNow Guru.

]]>
This post comes in response to a question I saw this morning on the ServiceNow forum. The request was to be able to create ‘Add me’ icons for user and group fields that would act the same way as the ‘Add me’ field on list fields. This post shows you how!

Add Me UI Macros

This functionality can be created for both user and group fields by adding a UI macro and associating it to the field in question. UI macros are defined by navigating to ‘System UI -> UI macros’ in your left nav.

‘Add me’ UI macro for user fields

‘add me’ UI macro
Name: add_me
XML:

<!--?xml version="1.0" encoding="utf-8" ?--><span id="${jvar_n}" class="btn btn-default icon-user-add" tabindex="0" title="Add me">
<span class="sr-only">Add me</span>
</span><script>
      function addMe(reference) {
         //Get the user reference field and populate the current user
         var s = reference.split('.');
         var referenceField = s[1];
         g_form.setValue(referenceField, '$[gs.getUserID()]');
      }
   </script>

–Once you’ve created the macro you need to invoke it on your user field by adding the ‘ref_contributions=add_me’ attribute to the dictionary of the user field.

‘Add me’ UI macro for ‘Assigned to’ fields

–Based on the comments below I realized that this is probably going to be used pretty often for a field like the ‘Assigned to’ field for tasks, where the user field is actually dependent on a group field like ‘Assignment group’. The problem with the script above in these situations is that it doesn’t respect the dependency, allowing you to add yourself even though you’re not a member of the currently-selected group.

Implementing an elegant workaround for this scenario becomes difficult because ServiceNow doesn’t natively provide group membership information to client scripts. I’ve come up with a nice workaround that uses the UI macro to cache that information when it is rendered at the server. The following UI macro code will add the ‘Add me’ UI macro to a field like ‘Assigned to’, but will alert users if they are not a member of the current assignment group.

‘add me’ UI macro FOR THE ‘Assigned to’ FIELD
Name: add_me
XML:

<!--?xml version="1.0" encoding="utf-8" ?--><span id="${jvar_n}" class="btn btn-default icon-user-add" tabindex="0" title="Add me">
<span class="sr-only">Add me</span>
</span>

<script>
      function addMe(reference) {
         //Hide any field messages
         g_form.hideFieldMsg('assigned_to', true);

         //Check to see if the user is a member of selected group
         var aGrp = g_form.getValue('assignment_group');
         var myGroups = '$[jvar_groups]';

         if(aGrp){
	        if(myGroups.indexOf(aGrp) > -1){
               //Get the user reference field and populate the current user
               var s = reference.split('.');
               var referenceField = s[1];
               g_form.setValue(referenceField, '$[gs.getUserID()]');
            }
	        else{
	           //Display a field error message
               g_form.showFieldMsg('assigned_to','You are not a member of the current assignment group.  Please select one of your groups and try again.','error');
	        }
	     }
         else{
	        //Get the user reference field and populate the current user
            var s = reference.split('.');
            var referenceField = s[1];
            g_form.setValue(referenceField, '$[gs.getUserID()]');
         }
      }
   </script>

 

‘Add my group’ UI macro for group fields

The group scenario is a bit more complicated because there’s not a built-in system concept of a primary group. Since each user can be a member of multiple groups you’ll need to decide how to deal with this in your environment. I think if I was setting it up, I’d put a ‘Primary’ field on the ‘sys_user_grmember’ table. This field could be modified by list editing the ‘Groups’ related list on the user form.

For this example, I’ve just set up the code so that it looks at the group membership table (and optionally for a ‘u_primary’ field on that table). The script finds the first group that matches the query (member of a group or having a primary group defined) and populates that group in the reference field. Otherwise, an alert appears indicating that the user isn’t a member of any groups or that a primary group doesn’t exist. You can adjust the ‘addMyGroup’ function below to meet your specific needs.

‘add_my_group’ UI macro
Name: add_my_group
XML:

<!--?xml version="1.0" encoding="utf-8" ?--><span id="${jvar_n}" class="btn btn-default icon-user-group" tabindex="0" title="Add my group">
<span class="sr-only">Add my group</span>
</span>
<script>

function addMyGroup(reference) {
   //Get the group reference field and populate the first group queried
   var s = reference.split('.');
   var referenceField = s[1];
   var grpRec = new GlideRecord('sys_user_grmember');
   grpRec.addQuery('user', '$[gs.getUserID()]');
   //Uncomment the following line if using a 'Primary' boolean field on the 'sys_user_grmember' table
   //grpRec.addQuery('u_primary', true);
   grpRec.query(groupCallback);

   //After the server returns the query recordset, continue here
   function groupCallback(grpRec){
      //Hide any previous field messages
      try{
         g_form.hideFieldMsg(referenceField, true);
      }catch(e){}
      
      //Check to see if the user is a member of a single group
      if(grpRec.next()){
         //Populate the first group found
         g_form.setValue(referenceField, grpRec.group);
      }
      else{
         g_form.showFieldMsg(referenceField,'You are not a member of any groups or have no primary group defined.','error');
      }
   }
}
</script>

–Once you’ve created the macro you need to invoke it on your group field by adding the ‘ref_contributions=add_my_group’ attribute to the dictionary of the group field.

‘add_me’ UI macro — FOR CATALOG VARIABLES!
The concepts above can also be applied to catalog variables. Unfortunately, ServiceNow doesn’t support field decorations or reference attributes for variables so the whole thing needs to be done with an ‘onLoad’ client script. Below is an example showing how to add the ‘Add me’ icon next to a user reference variable named ‘caller_id’. This concept can be extended to work with most catalog variables by changing the variable name and removing ‘lookup.’ from the script below for non-reference variables. Then you just have to adjust the various element attributes and ‘onclick’ function to use it in other ways.

function onLoad() {
//The variable name to put the icon next to
var varName = 'caller_id';try{
//Add the icon decoration to the reference field
//If not reference variable, remove 'lookup.' below
var varEl = 'lookup.' + g_form.getControl(varName).id;
$(varEl).insert({
after: '<a id="add_me_macro" class="btn btn-default sc-ref-spacer icon-user sn-tooltip-basic" title="" data-original-title="Add me"></a>'
});
//Add the 'onclick' event
$('add_me_macro').observe('click', addMe);
}catch(e){}

function addMe(){
//Add current user to reference field
g_form.setValue(varName, g_user.userID);
}
}

The post ‘Add Me’ UI macro for User and Group Fields appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-macros/add-me-ui-macro-user-group-fields/feed/ 62
CI UI Macro Actions for the Affected CIs List https://servicenowguru.com/cmdb/show-bsm-ci-map-affected-cis-related-list/ https://servicenowguru.com/cmdb/show-bsm-ci-map-affected-cis-related-list/#comments Wed, 18 Jan 2012 13:12:25 +0000 https://servicenowguru.wpengine.com/?p=4252 The ability to associate Affected Configuration Items against a task is one of the most basic pieces of the various task forms in ServiceNow. ServiceNow gives you the ‘Configuration Item’ field to associate a single CI and the ‘Affected CIs’ related list in the event that your task needs to be associated to multiple CIs.

The post CI UI Macro Actions for the Affected CIs List appeared first on ServiceNow Guru.

]]>
The ability to associate Affected Configuration Items against a task is one of the most basic pieces of the various task forms in ServiceNow. ServiceNow gives you the ‘Configuration Item’ field to associate a single CI and the ‘Affected CIs’ related list in the event that your task needs to be associated to multiple CIs. I’ve written before about the benefits of tracking all of this information in one place to simplify reporting and usage requirements. During an onsite visit with a customer this week I noticed another opportunity to improve the functionality of the ‘Affected CIs’ related list. It would be very useful to be able to right-click items in the ‘Affected CIs’ related list and show a BSM Map or associated tasks just like you can do for the ‘Configuration Item’ field UI Macro icons. This post will show you how you can set these list context UI Actions up in your instances.

Configuration Item Reference Icons

Configuration Item Context Actions

Add a UI Action Context Menu to Show a BSM Map for a CI

This UI Action allows you to access (via a right-click context menu) a Business Service Map for any Configuration Item listed in the ‘Affected CIs’ related list.

Special thanks to Peter Oneppo for building the bulk of this script during a customer visit we had together this week!

‘Show CI map’ UI action
Name: Show CI map
Table: CI’s Affected (task_ci)
List context menu: True
Show insert: True
Show update: True
Client: True
Onclick: showBSMMapList()
Condition: gs.hasRole(‘itil’) && RP.isRelatedList()
Script:

function showBSMMapList() {
//Retrieve the 'Affected CI' record
var sysId = typeof rowSysId == 'undefined' ? gel('sys_uniqueValue').value : rowSysId;
var gr = new GlideRecord('task_ci');
gr.get(sysId);//Build the BSM map URL
var attribs = 'table=cmdb_ci';
attribs += ',id=' + gr.ci_item;
attribs += ',level=4';
attribs += ',ref=' + g_form.tableName + '.cmdb_ci';
attribs += ',ciview=';
attribs += ',restack=true';
var url = new GlideURL('bsm_map2.do');
url.addParam('sysparm_nameofstack', 'bsm');
url.addParam('sysparm_attributes', attribs);

//Open the BSM map URL in a new window
var w = getTopWindow();
w.popupOpenFocus(url.getURL(), 'show_bsm_map', 950, 700, '', false, false);
}

If you’ve set up the UI Action correctly, you should now be able to right-click a row in the ‘Affected CIs’ related list and display a BSM map by clicking the ‘Show CI Map’ option.

CI Context Action - CI BSM Map

Add a UI Action Context Menu to Show Related Tasks for a CI

Using a similar concept to that described above, you can create a context menu UI Action to display a dialog containing all associated, active tasks for any Configuration Item in the ‘Affected CIs’ related list.

‘Show Related Tasks’ UI action
Name: Show Related Tasks
Table: CI’s Affected (task_ci)
List context menu: True
Show insert: True
Show update: True
Client: True
Onclick: showTasksDialogList()
Condition: gs.hasRole(‘itil’) && RP.isRelatedList()
Script:

function showTasksDialogList() {
//Retrieve the 'Affected CI' record
var sysId = typeof rowSysId == 'undefined' ? gel('sys_uniqueValue').value : rowSysId;
var gr = new GlideRecord('task_ci');
gr.get(sysId);//Create and display the GlideDialogWindow
var w = new GlideDialogWindow('show_list');
w.setTitle('Other active tasks affecting this Configuration Item');
w.setPreference('table', 'task_list');
w.setPreference('sysparm_view', 'default');
w.setPreference('sysparm_query', "active=true^sys_id!=" + g_form.getUniqueValue() + "^SUBQUERYsys_id,task,task_ci^ci_item=" + gr.ci_item + "^ENDSUBQUERY^GROUPBYsys_class_name");
w.render();
}

If you’ve set up the UI Action correctly, you should now be able to right-click a row in the ‘Affected CIs’ related list and display a dialog showing open tasks for the CI by clicking the ‘Show Related Tasks’ option.

CI Context UI Action - Show Tasks

The post CI UI Macro Actions for the Affected CIs List appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/cmdb/show-bsm-ci-map-affected-cis-related-list/feed/ 4
Collapsible CMS Menus https://servicenowguru.com/content-management/collapsible-cms-menus/ https://servicenowguru.com/content-management/collapsible-cms-menus/#comments Wed, 17 Aug 2011 13:50:35 +0000 https://servicenowguru.wpengine.com/?p=3949 Recently I worked on a content management system (CMS) deployment for a customer. One of their requirements was to present a collapsible menu structure on a few pages containing links to catalog items, KB articles, etc. The menu piece is simple. ServiceNow provides several ways to construct CMS menus without requiring any code. The less

The post Collapsible CMS Menus appeared first on ServiceNow Guru.

]]>
Recently I worked on a content management system (CMS) deployment for a customer. One of their requirements was to present a collapsible menu structure on a few pages containing links to catalog items, KB articles, etc. The menu piece is simple. ServiceNow provides several ways to construct CMS menus without requiring any code. The less simple part was making a collapsible menu. In this post I’ll explain the solution I came up with to provide a collapsible menu system that leverages the existing menu system in the ServiceNow CMS.

Collapsible Menu Page

The approach I had seen taken in the past with collapsible menus was to leverage some sort of jQuery plugin to pull in the menu items from the database. I considered this approach, but wanted something that was closer to the existing menu setup. I really didn’t want to have to include jQuery and deal with the extra burden of a completely separate library just for this purpose.

What I came up with is a fairly simple solution that overlays the existing menu HTML of a ‘Vertical Blocks’ menu with some javascript that manages the expand/collapse functionality.

Setting up the menu(s)…

The first step is to set up your menus. The only important part of this step for this solution is to make sure your menu is a VERTICAL BLOCKS menu. Other than that, simply create the menu, add sections and items below it, and include any icons you want to use. If you want to have a page with a 2-column menu setup, you’ll need to create a separate menu for each column.
Navigation Menu

Creating the content blocks…

Once you’ve created the menu(s) you need to create a dynamic content block that contains the code to add expand/collapse functionality to the menu. The code below can be used as-is in a dynamic content block in your system.

‘Collapsible Menu Script’ Dynamic Content Block
Name: Collapsible Menu Script
Dynamic content:

<!--?xml version="1.0" encoding="utf-8" ?-->
<table cellpadding="5">
<tbody>
<tr>
<td id="expandAllImg"><a><img src="images/icons/nav_expandall.gifx" /><b> Expand all</b></a></td>
<td id="collapseAllImg" style="display: none;"><a><img src="images/icons/nav_collapseall.gifx" /><b> Collapse all</b></a></td>
</tr>
</tbody>
</table>
<script>
Event.observe(window, 'load', function() {
  var sections = $$('tr.cms_menu_vertical_blocks_top_section');
   sections.each(function(s) {
      //If subitems
      if(s.next()){
         //Hide the subitems and add the collapse image
         s.next().hide();
         var collapseImg = s.down().insert({
            top: '<a><img src="images/arrows_expand_sm.gifx" alt="Expand" title="Expand" class="collapse_menu_icon"></img></a>'
         });
         collapseImg.down('img').observe('click', toggleSectionItems);
      }
   });
});

function toggleSectionItems(event) {
   var element = event.element();
   if(element.getAttribute('title') == 'Expand'){
      element.title = 'Collapse';
      element.src = 'images/arrows_collapse_sm.gifx';  
      element.alt = 'Collapse';
   }
   else{
      element.title = 'Expand';
      element.src = 'images/arrows_expand_sm.gifx';  
      element.alt = 'Expand';
   }
   element.up('tr.cms_menu_vertical_blocks_top_section').next().fadeToggle();
}

function showSectionItems() {
   var sections = $$('tr.cms_menu_vertical_blocks_top_section');
   sections.each(function(s) {
      //If subitems
      if(s.next()){
         s.next().fadeIn();
      }
   });
   $('collapseAllImg').show();
   $('expandAllImg').hide();
   $$('.collapse_menu_icon').each(function(i) {
      i.title = 'Collapse';
      i.src = 'images/arrows_collapse_sm.gifx';  
      i.alt = 'Collapse';
   });
}

function hideSectionItems() {
   var sections = $$('tr.cms_menu_vertical_blocks_top_section');
   sections.each(function(s) {
      //If subitems
      if(s.next()){
         s.next().fadeOut();
      }
   });
   $('collapseAllImg').hide();
   $('expandAllImg').show();
   $$('.collapse_menu_icon').each(function(i) {
      i.title = 'Expand';
      i.src = 'images/arrows_expand_sm.gifx';  
      i.alt = 'Expand';
   });
}
</script>

If you are setting up a 2-column menu page you’ll also want to create a spacer content block so that your menus line up correctly on the page.

‘Collapsible Menu Spacer’ Dynamic Content Block
Name: Collapsible Menu Spacer
Dynamic content:

<!--?xml version="1.0" encoding="utf-8" ?-->
<div style="margin-top: 27px;"></div>

 

Setting up the page

Finally, you can set up the actual CMS page containing your menu and the content block (or blocks if you’re doing a 2-column menu). The page setup should look something like the screenshot here…
Collapsible Menu Page Setup

If you’ve set everything up correctly you should have a nice menu page with collapsible menus! Each menu section can be expanded individually to show the items underneath it. You can also use the ‘Expand all/Collapse all’ toggle to show and hide all items under all sections on the page.
Collapsible Menu Page

The post Collapsible CMS Menus appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/content-management/collapsible-cms-menus/feed/ 8
Building a CI Change Calendar Macro – On The Fly https://servicenowguru.com/reporting/ci-change-calendar-macro/ https://servicenowguru.com/reporting/ci-change-calendar-macro/#comments Wed, 20 Jul 2011 12:39:19 +0000 https://servicenowguru.wpengine.com/?p=3920 A co-worker asked me for some help yesterday fulfilling an interesting requirement. He needed to set up a configuration item reference field or catalog variable that would display a calendar macro that, when clicked, would open a popup window containing a change calendar report for that configuration item. I figured this idea might be of

The post Building a CI Change Calendar Macro – On The Fly appeared first on ServiceNow Guru.

]]>
A co-worker asked me for some help yesterday fulfilling an interesting requirement. He needed to set up a configuration item reference field or catalog variable that would display a calendar macro that, when clicked, would open a popup window containing a change calendar report for that configuration item. I figured this idea might be of use to others so I’m posting it here!

CI Change Calendar Report Macro Popup

I’ve written before about UI macros, and different types of popups on SNGuru. I’ve also written about how your change management process can be a valuable input into your other ITIL processes such as incident management. You can refer to those posts if you’re interested in more detail on some of the ideas used in this article.

The real magic of this solution is how you can create this calendar report ‘on-the fly’ simply by constructing the correct URL. This is something that a colleague of mine, Bobby Edmonds, tipped me off to a couple of years ago. The URL contains several ‘sysparm_’ parameters that point to the fields on the report form. Once you know those, you just have to pass them the correct values. The URL for the calendar report needs to look something like this…

sys_report_template.do?sysparm_table=change_request&sysparm_type=calendar&sysparm_cal_field=end_date&sysparm_from_list=true&sysparm_manual_labor=true&sysparm_query=^end_date%3Ejavascript:gs.endOfLastMonth()'^cmdb_ci=YOUR_CI_SYS_ID_HERE
I plan on writing a post about creating on-the-fly reports soon, but you can piece together the necessary URL parameters for a report by poking around any existing report in your system with a DOM inspector to see what parameters are necessary.

You might be asking, “Why don’t you just point directly to the existing change calendar report URL?”. You could certainly do that, and avoid all of the above, but the requirement in this case is to have the calendar report filtered based on the CI chosen in the field, so it needs to be dynamic.

Because this URL will be initiated from a UI macro (for this example) we’ll need to escape the ampersands and you can see that I’ve done that in the code below. The rest of the code is almost identical to the out-of-box ‘user_show_incidents’ UI macro that you see on the incident ‘Caller’ field. Once the URL is constructed we can use ‘popupOpen’ to display the report in a popup!

Your UI macro should look like this. Once set up, it can be added to the CI reference field of your choice by adding the ‘ref_contributions=ci_show_change_calendar’ attribute to the dictionary entry ‘Attributes’ field of that CI reference field.

‘ci_show_change_calendar’ UI macro
Name: ci_show_change_calendar
Description:
Show CI change calendar popup link
Activate by:
– set the active field in this macro to true
– adding the attribute to a dictionary field: ref_contributions=ci_show_change_calendar
Script:

<!--?xml version="1.0" encoding="utf-8" ?-->



<script>
function showCIChangeCalendar(reference) {
   //Construct the calendar report URL
   var url = 'sys_report_template.do?sysparm_table=change_request$[AMP]sysparm_type=calendar$[AMP]sysparm_cal_field=end_date$[AMP]sysparm_from_list=true$[AMP]sysparm_manual_labor=true$[AMP]sysparm_query=^end_date%3Ejavascript:gs.endOfLastMonth()^cmdb_ci=';
   
   var s = reference.split('.');
   var referenceField = s[1];
   var v = g_form.getValue(referenceField);
   url = url + v;
   //Open the popup 
   var features = "width=700,height=650,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollbars=1";
   popupOpen(url, 'show_calendar', 700, 650, features, true);
}
</script>

 

Add a Change Calendar Macro to a Catalog Reference Variable

You can use a similar technique to add a calendar macro icon next to a catalog reference variable. The big, additional challenge in the service catalog is that reference field macros are not supported for catalog variables. In order to add one you have two options. The first would be to create a UI page or UI macro-type variable similar to the example above. The big drawback would be that the icon wouldn’t appear right next to the reference variable without some clever client scripting.
The second option (which I chose) is to use a catalog client script to construct the macro on-the-fly and place it in the correct spot next to the reference field. This technique is based on a previous solution I wrote about in another SNCGuru article about placing macros next to non-reference fields.

Your catalog client script should look like this. Just add the name of your CI reference variable in the ‘ciVarName’ line below.

‘Add CI Change Calendar Macro’ Catalog Client Script
Name: Add CI Change Calendar Macro
Applies to: Catalog item or variable set of your choice
Type: onLoad
Script (Pre-Fuji version):

function onLoad() {
//The reference variable name to put the icon next to
var ciVarName = 'cmdb_ci';//Add the icon decoration to the reference field
var ciEl = 'lookup.' + g_form.getControl(ciVarName).id;
$(ciEl).insert({
after: '<a id="cmdb_ci_calendar_macro" style="padding-right: 4px;"></a><img title="CI Change Calendar" src="images/icons/dayview.gifx" alt="CI Change Calendar" />'
});
//Add the 'onclick' event
$('cmdb_ci_calendar_macro').observe('click', showCIChangeCalendar);

function showCIChangeCalendar(){
//Construct the calendar report URL
var url = 'sys_report_template.do?sysparm_table=change_request&sysparm_type=calendar&sysparm_cal_field=end_date&sysparm_from_list=true&sysparm_manual_labor=true&sysparm_query=^end_date%3Ejavascript:gs.endOfLastMonth()';
if(g_form.getValue(ciVarName) != ''){
url = url + '^cmdb_ci=' + g_form.getValue(ciVarName);
}

//Open the popup
var features = "width=700,height=650,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollbars=1";
popupOpen(url, 'show_calendar', 700, 650, features, true);
}
}

Script (Fuji version):

function onLoad() {
//The reference variable name to put the icon next to
var ciVarName = 'cmdb_ci';

//Add the icon decoration to the reference field
var ciEl = 'lookup.' + g_form.getControl(ciVarName).id;
$(ciEl).insert({
after: '<a id="cmdb_ci_calendar_macro" class="icon-calendar btn btn-default sn-tooltip-basic" style="padding: 6px 10px; vertical-align: text-bottom;" title="" data-original-title="CI Change Calendar"></a>'
});
//Add the 'onclick' event
$('cmdb_ci_calendar_macro').observe('click', showCIChangeCalendar);

function showCIChangeCalendar(){
//Construct the calendar report URL
var url = 'sys_report_template.do?sysparm_table=change_request&sysparm_type=calendar&sysparm_cal_field=end_date&sysparm_from_list=true&sysparm_manual_labor=true&sysparm_query=^end_date%3Ejavascript:gs.endOfLastMonth()';
if(g_form.getValue(ciVarName) != ''){
url = url + '^cmdb_ci=' + g_form.getValue(ciVarName);
}

//Open the popup
var features = "width=700,height=650,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollbars=1";
popupOpen(url, 'show_calendar', 700, 650, features, true);
}
}

When you’re done, your catalog variable will have a calendar link next to it that looks like this…
CI Change Calendar Macro Catalog Variable

The post Building a CI Change Calendar Macro – On The Fly appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/reporting/ci-change-calendar-macro/feed/ 5
Solving the Client Script ‘Before and After’ Problem https://servicenowguru.com/system-ui/solving-client-script-before-after-problem/ https://servicenowguru.com/system-ui/solving-client-script-before-after-problem/#comments Mon, 13 Jun 2011 15:03:01 +0000 https://servicenowguru.wpengine.com/?p=3789 Every now and then I come across a question dealing with the order of execution for client-side code (Client Scripts and UI Policies). In my experience, the need to order client-side code is pretty rare and really only applies in a few ‘onLoad’ scenarios and even fewer ‘onChange’ scenarios. Usually, the way that a browser

The post Solving the Client Script ‘Before and After’ Problem appeared first on ServiceNow Guru.

]]>
Every now and then I come across a question dealing with the order of execution for client-side code (Client Scripts and UI Policies). In my experience, the need to order client-side code is pretty rare and really only applies in a few ‘onLoad’ scenarios and even fewer ‘onChange’ scenarios. Usually, the way that a browser parses and executes client-side code means that the ordering is pretty unpredictable. It’s worth mentioning that this issue doesn’t exist with server-side code precisely because the browser isn’t involved (which is why you can neatly order all of your business rules without issue).

In this post I’ll show you some of the techniques I’ve used in the past to provide some control over the order of execution of client-side code. I’ll also show you a pretty cool trick that you can use to ensure that a piece of client-side code runs before any other client script or UI policy…or after ALL of those scripts finish running.

Solving the ‘before…and after’ problem

The first thing you should be aware of is that you do have some limited ability built-in to control the order of execution for client-side code with the ‘Order’ field on UI policies.

UI Policy Order

There are a few caveats with the ordering of client-side code though.

  1. Ordering IS NOT available to client scripts, only UI policies
  2. Client scripts will start their execution before UI policies
  3. Even with the order field on the UI policies, it only controls the start order of execution for the scripts. The actual order that various portions of those scripts run depends on the complexity and variety of the scripts so you can’t really guarantee that a particular piece of client-side code will run before or after another.

You can also set up a wait or delay in your script by using the ‘setTimeout’ method (or something similar).

Guaranteeing absolute before…and after…

I was recently asked to help solve a problem with a long-loading form. The form took several seconds to render and hide various form sections, fields, and related lists. The problem was that during this time, users could interact with the form before it was ready to use. This can cause issues with incorrect submissions, mis-routed calls, and the general undoing of all of the great things you designed the form to do in the first place. Before I explain this solution you should know that the overwhelming majority of issues in this area can be prevented by following a few simple rules…

  • Limit the amount of information on your form to what is absolutely necessary. Dozens of form sections and related lists and hundreds of fields on a form just aren’t going to load quickly no matter what you do…even if they’re hidden!
  • Stay away from ‘GlideRecord’, ‘getReference’, and ‘GlideAJAX’ in your client scripts and UI policies! If you do need to use any of these then use asynchronous processing if at all possible!
  • Follow these best practice guidelines in your client scripts.

Sometimes process and bureaucracy win out over performance and sensibility however, and you have to deal with a problem that you would rather avoid in the first place. One idea would be to use the loading dialog that I described in a previous post on ServiceNowGuru. This would prevent user interaction with the form until the entire thing finished loading and all of the scripts had finished their execution.

Long Loading Form Dialog

The dialog is easy enough to execute, but the real problem is guaranteeing that the dialog displays before anything else on the form (which you can’t do with client scripts or UI policies) and knowing definitively when the form finishes loading so that you can close the dialog.

There’s simply no way to guarantee that a client script or UI policy will run before the form loads. The actual fields (and formatters) will be rendered before the scripts run though. The solution I came up with was to create a custom hidden field (by utilizing a UI macro and UI formatter) to execute some code before any other client scripts run. The script is actually very simple. It just shows the loading dialog, uses Prototype’s ‘Event.observe’ function to identify when the form has finished loading, and hides the dialog.

//Show the loading dialog immediately as the form loads
var loadingDialog = new GlideDialogWindow("dialog_loading", true);
loadingDialog.setPreference('table', 'loading');
loadingDialog.setTitle('Loading...'); //Set the loading dialog title here...
loadingDialog.render();
                  
//Wait until the form has finished loading
addLateLoadEvent(function(){
    loadingDialog.destroy();
});

You can set up the UI macro and UI formatter as follows…

‘form_loading_dialog’ UI macro
Name: form_loading_dialog
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_show_dialog" expression="!RP.isPopup()" />
   <j:if test="${jvar_show_dialog}" >
      <script>
         //Show the loading dialog immediately as the form loads
         var loadingDialog = new GlideDialogWindow("dialog_loading", true);
         loadingDialog.setPreference('table', 'loading');
         loadingDialog.setTitle('Loading...'); //Set the loading dialog title here...
         loadingDialog.render();
                  
         //Wait until the form has finished loading
         addLateLoadEvent(function(){
             loadingDialog.destroy();
         });
      </script>
   </j:if>
</j:jelly>
‘Form Loading Dialog’ Formatter
Name: Form Loading Dialog
Formatter: form_loading_dialog (or the name of your UI macro)
Table: Task
Type: Formatter

Once you’ve set up the UI macro and UI formatter for the table(s) of your choice, all you have to do is personalize the form for any long-loading form and add the ‘Form Loading Dialog’ formatter to the first form section on the form. Enjoy!

Personalize Form Loading Dialog

The post Solving the Client Script ‘Before and After’ Problem appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-ui/solving-client-script-before-after-problem/feed/ 47
On-call Schedule Popup UI Macro https://servicenowguru.com/ui-macros/on-call-calendar-popup-ui-macro/ https://servicenowguru.com/ui-macros/on-call-calendar-popup-ui-macro/#comments Mon, 09 May 2011 16:24:29 +0000 https://servicenowguru.wpengine.com/?p=3623 Here’s a UI macro that I’ve used for a couple of clients that allows you to pop open an on-call rotation schedule for the group selected in any ‘Group’ reference field in the system. This will probably be most useful for the ‘Assignment group’ table that you use on the task table. As with any

The post On-call Schedule Popup UI Macro appeared first on ServiceNow Guru.

]]>
Here’s a UI macro that I’ve used for a couple of clients that allows you to pop open an on-call rotation schedule for the group selected in any ‘Group’ reference field in the system. This will probably be most useful for the ‘Assignment group’ table that you use on the task table. As with any reference field UI macro, you can add the UI macro to your reference field by adding the ‘ref_contributions’ attribute to the dictionary entry of your reference field. So this macro would require the ‘ref_contributions=show_group_on_call_schedule’ attribute. Since it displays on-call information, it is also dependent on the ‘on_call scheduling’ plugin being installed.

SNOnCallSchedule

Here’s the code you’ll need for your UI macro. This code should work without modification for any group reference field in your system.

‘show_group_on_call_schedule’ UI Macro
Name: show_group_on_call_schedule
Description: Displays an on-call schedule for the selected assignment group.
Requires ‘ref_contributions=show_group_on_call_schedule’ dictionary attribute.
XML:

<!--?xml version="1.0" encoding="utf-8" ?-->



<span id="${jvar_n}" class="btn btn-default icon-date-time" tabindex="0" title="${gs.getMessage('Show group on-call schedule')}">
<span class="sr-only">${gs.getMessage('Show group on-call schedule')}</span>
</span><script>
function showOnCallSchedule(reference){
   //Get the current group
   var group = g_form.getValue(reference.split('.')[1]);
   //Query to see if an on-Call rotation exists
   var grpRota = new GlideRecord('cmn_rota');
   grpRota.addQuery('group', group);
   grpRota.addQuery('active', true);
   grpRota.query();
   if(grpRota.hasNext()){
      //Construct a URL for the popup window
      var url = 'show_schedule.do?sysparm_type=roster$[AMP]sysparm_zoom=weekly$[AMP]sysparm_group_id=' + group;
      //Open the popup
      popupOpenStandard(url);
   }
   else{
      alert('No active rotation specified for the selected group.');
   }
}
</script>

The post On-call Schedule Popup UI Macro appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-macros/on-call-calendar-popup-ui-macro/feed/ 21
Adding Referenced Records Without Leaving the Form https://servicenowguru.com/ui-macros/adding-referenced-records-leaving-form/ https://servicenowguru.com/ui-macros/adding-referenced-records-leaving-form/#comments Thu, 24 Mar 2011 11:13:15 +0000 https://servicenowguru.wpengine.com/?p=3508 One 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

The post Adding Referenced Records Without Leaving the Form appeared first on ServiceNow Guru.

]]>
One 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" ?-->



<a id="${jvar_n}"></a>
<img title="${gs.getMessage('Add/Edit User')}" src="images/icons/user_profile.gifx" alt="${gs.getMessage('Add/Edit User')}" border="0" />
<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>

XML (Fuji version):

<!--?xml version="1.0" encoding="utf-8" ?-->





<a>
<span id="${jvar_n}" class="btn btn-default icon-add-circle" title="${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>


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

The post Adding Referenced Records Without Leaving the Form appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-macros/adding-referenced-records-leaving-form/feed/ 35
Lock/Unlock glide_list and URL Fields With Client Scripts https://servicenowguru.com/client-scripts-scripting/lock-unlock-glidelist-url-fields-client-scripts/ https://servicenowguru.com/client-scripts-scripting/lock-unlock-glidelist-url-fields-client-scripts/#comments Tue, 01 Mar 2011 14:10:48 +0000 https://servicenowguru.wpengine.com/?p=3417 I’ve answered several questions in the past about the functionality of lock icons in Service-now. Lock icons appear on glide_list and URL fields. The most-common example is the ‘Watch list’ field on the task table. Service-now provides some system properties to manage the default lock appearance of these field types. There are times when a

The post Lock/Unlock glide_list and URL Fields With Client Scripts appeared first on ServiceNow Guru.

]]>
I’ve answered several questions in the past about the functionality of lock icons in Service-now. Lock icons appear on glide_list and URL fields. The most-common example is the ‘Watch list’ field on the task table. Service-now provides some system properties to manage the default lock appearance of these field types. There are times when a global system property doesn’t really meet the need you have however, and you need to lock or unlock these fields automatically using script. In this article I’ll explain how I’ve done these types of things before.

GlideList-URL-Lock Fields

System Properties

First, the system properties. These can be found by navigating to ‘System Properties -> UI Properties’. Obviously they’re very simple to set, but they will apply system-wide, which limits their usefulness in many cases.

  • ‘Glide lists start out locked’ (glide.ui.glide_list.start.locked) – Controls the default lock behavior of ALL glide_list fields on form load
  • ‘Unlock empty URL fields on form load’ (glide.ui.unlock_empty_url) – Controls the default lock behavior of all empty URL fields on form load

Client Scripts

For more control over the lock/unlock behavior of these field types, you’ll need to use client scripts or UI policies. Here are some examples…

Lock/Unlock glide_list Fields

Lock glide_list field named ‘watch_list’ (Replace every instance of ‘watch_list’ with the name of your field and every instance of ‘incident’ with the name of the table the script runs against)

$('incident.watch_list_lock').click();

Unlock glide_list field named ‘watch_list’ (Replace every instance of ‘watch_list’ with the name of your field and every instance of ‘incident’ with the name of the table the script runs against)

$('incident.watch_list_unlock').click();

Lock/Unlock URL Fields

Lock URL field named ‘u_url’ (Replace every instance of ‘u_url’ with the name of your field and every instance of ‘incident’ with the name of the table the script runs against)

$('incident.u_url_lock').click();

Unlock URL field named ‘u_url’ (Replace every instance of ‘u_url’ with the name of your field and every instance of ‘incident’ with the name of the table the script runs against)

$('incident.u_url_unlock').click();

Advanced Custom Locking Scripts

Show/hide fields based on lock/unlock
This onLoad client script shows/hides the ‘short_description’ field when you click the lock/unlock icons on the ‘watch_list’ field. What you have to do to get this to work is define a custom event handler in your ‘onLoad’ client script. In this case, there is a built-in ‘onclick’ event that you need to access. You can see what the IDs and events are by using a DOM inspector like firebug in a Firefox browser. You can customize which field gets hidden by modifying the ‘g_form.setDisplay’ lines in the script below.

function onLoad() {
   //Get the control of the unlock icon
   var unlockControl = g_form.getControl('watch_list_unlock');
   //Set its onclick method
   unlockControl.onclick = unlockClick;
 
   //Get the control of the lock icon
   var lockControl = g_form.getControl('watch_list_lock');
   //Set its onclick method
   lockControl.onclick = lockClick;
}
 
function unlockClick() {
   g_form.setDisplay('short_description', false);
   unlock(this, 'incident.watch_list', 'incident.watch_list_edit', 'incident.watch_list.nonedit');
}
 
function lockClick(){
   g_form.setDisplay('short_description', true);
   lock(this, 'incident.watch_list', 'incident.watch_list_edit', 'incident.watch_list_nonedit', 'select_0incident.watch_list', 'incident.watch_list_nonedit');
}

Creating a custom lock icon for any form element
You can also add custom lock icons to other form elements. One example I’ve written in the past is a lock icon situated next to the ‘Category’ field on an incident form. Clicking the lock icon displays or hides other categorization fields. Check out the ‘Adding a UI Macro to a Non-reference Field’ article for more information.

The post Lock/Unlock glide_list and URL Fields With Client Scripts appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/client-scripts-scripting/lock-unlock-glidelist-url-fields-client-scripts/feed/ 14