UI macros Archives - ServiceNow Guru https://servicenowguru.com/category/ui-macros/ ServiceNow Consulting Scripting Administration Development Tue, 28 May 2024 21:37:08 +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/category/ui-macros/ 32 32 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
Mandatory Knowledge Search Before Ticket Creation https://servicenowguru.com/client-scripts-scripting/mandatory-knowledge-search-ticket-creation/ https://servicenowguru.com/client-scripts-scripting/mandatory-knowledge-search-ticket-creation/#comments Mon, 14 May 2012 12:37:38 +0000 https://servicenowguru.wpengine.com/?p=4399 Greetings from Knowledge12 in New Orleans! I’ll be here all week with CrossFuze Solutions so if you’re here and see me, please introduce yourself. I’m looking forward to putting a face to all of the names of people I’ve worked with remotely. I’m working with a client currently who wants to encourage the use of

The post Mandatory Knowledge Search Before Ticket Creation appeared first on ServiceNow Guru.

]]>
Greetings from Knowledge12 in New Orleans! I’ll be here all week with CrossFuze Solutions so if you’re here and see me, please introduce yourself. I’m looking forward to putting a face to all of the names of people I’ve worked with remotely.

I’m working with a client currently who wants to encourage the use of their Knowledge Base to reduce their ticket load. This, of course, is a common requirement but it’s one that I don’t think is adequately addressed in ServiceNow currently. In this post I’ll share my implementation of their idea. I don’t think it’s a perfect solution, but it might give you some ideas to improve your own process and design. This post shows how you can force a KB search using the standard search dialog whenever a user creates an incident. I’ve designed the solution to work in a standard incident form and within the service catalog so that it can be applied in whatever way you create tickets in your environment.
Automatic KB Popup

When I designed this solution, my main concern was to implement a solution that would promote the Knowledge Base search without being completely annoying to the end user. Because of this, I wanted to be very careful about allowing specific control over the event trigger that produces the KB popup window. I also wanted the solution to use as much of the out-of-box behavior as possible.

The solution I decided on was to use a client script to add a ‘blur’ event to the ‘Short Description’ field. The ‘blur’ event for a field runs when the field loses focus. In the case of the ‘Short Description’ field, it runs when somebody clicks into the field, and then clicks somewhere else. I also wanted the script to only run for a new record and only to run when there was an actual value in ‘Short Description’.

From a Standard Form Field

This script can be pasted directly into any ‘onLoad’ client script on a standard form field. The only requirements are that the form includes a field named ‘short_description’ and that field uses the standard KB search icon.

‘Pop KB Search from Short Description’
Name: Pop KB Search from Short Description
Table: Incident
Type: onLoad
Script:

function onLoad() {
//Set the maximum number of times the popup will appear
var maxKBPop = 1;
var kbPopCount = 0;//Only run for new records
if(g_form.isNewRecord()){
//Add an 'onBlur' event to search KB from 'short_description' field
var field = g_form.getControl('short_description');
Event.observe(field, 'blur', function() {
//Only search if there is a value
if(g_form.getValue('short_description') != ''){
//Only pop the search one time
if(kbPopCount < maxKBPop){
kbPopCount++;
customKBPopup(field.id);
}
}
});
}
}
function customKBPopup(me) {
self.fillField = me;
var shortElement = gel(me);
var searchText = shortElement.value;
var url = 'kb_find.do?sysparm_search=' + encodeURI(searchText);
url += "&sysparm_nameofstack=kbpop";
url += "&sysparm_kb_search_table=" + g_form.getTableName();
url += "&sysparm_operator=IR_AND_OR_QUERY";
popupOpenStandard(url, 'kb2task');
}

From a Service Catalog Variable

You can also force a KB search with a catalog variable (on a record producer or catalog item). The script below assumes that you’ve got a string field named ‘short_description’. Because the knowledge icon doesn’t exist for service catalog variables, the script manufactures the icon and link on the fly so that it behaves just like the standard field.

‘Pop KB Search from Short Description’
Name: Pop KB Search from Short Description
Type: onLoad
Script:

//Add an event handler to pop KB Search when focus moves from Short Description field
function onLoad() {
//Set the maximum number of times the popup will appear
var maxKBPop = 1;
var kbPopCount = 0;
var field = g_form.getControl('short_description');
//Add the KB Search icon
$(field.id).up(1).insert('<a><img class="knowledge" title="Search Knowledge" src="images/icons/knowledge.gifx" width="16" height="16" border="0" /></a></td');
$('status.' + field.id).up('td').setAttribute('colSpan', '3');//Add an 'onBlur' event to search KB from 'short_description' field
Event.observe(field, 'blur', function() {
//Only search if there is a value
if(g_form.getValue('short_description') != ''){
//Only pop the search one time
if(kbPopCount < maxKBPop){
kbPopCount++;
kbPopupSC();
}
}
});
}function kbPopupSC() {
var shortElement = $(g_form.getControl('short_description').id);
var searchText = shortElement.value;
var url = 'kb_find.do?sysparm_search=' + encodeURIComponent(searchText);
url += "&sysparm_operator=IR_AND_OR_QUERY";

popupOpenStandard(url, "kb2task");
}

The post Mandatory Knowledge Search Before Ticket Creation appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/client-scripts-scripting/mandatory-knowledge-search-ticket-creation/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
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
Direct User Impersonation From a User Record https://servicenowguru.com/ui-actions-system-ui/direct-impersonation-user-record/ https://servicenowguru.com/ui-actions-system-ui/direct-impersonation-user-record/#comments Fri, 10 Dec 2010 13:53:20 +0000 https://servicenowguru.wpengine.com/?p=3080 Every now and then I get a tip from a SNCGuru reader. This post comes courtesy of Garrett Griffin who emailed me yesterday with a cool script that his organization uses to allow admins to easily impersonate users without even having to select their name from the impersonate dialog. For those of you who don’t

The post Direct User Impersonation From a User Record appeared first on ServiceNow Guru.

]]>
Every now and then I get a tip from a SNCGuru reader. This post comes courtesy of Garrett Griffin who emailed me yesterday with a cool script that his organization uses to allow admins to easily impersonate users without even having to select their name from the impersonate dialog. For those of you who don’t know about user impersonation in Service-now yet, you can read about it here. The method that Garrett shared is more convenient in many cases than the regular impersonate button and it also helps to eliminate the confusion that can be caused in the standard impersonate dialog when you’ve got more than one user with the same display name.

The scripts below use the exact same method as the regular impersonation dialog. The only difference is that they feed the user ID directly to the URL, which eliminates the need for you to choose a user to impersonate. This can be helpful when you’ve got a user record up and you want to impersonate from that user record, or when you are troubleshooting a bug in your Service-now instance that someone has reported in an incident. You can set up a UI action and/or a UI macro to easily impersonate the appropriate user in either of these scenarios.

Here’s how you could create a UI Action on the User form…

‘Impersonate’ UI Action
Name: Impersonate
Table: User (sys_user)
Action name: impersonateUser
Client: True
Form button: True
Onclick: impersonateUser()
Condition: gs.hasRole(‘admin’) && current.active == true && current.locked_out == false
Script:

function impersonateUser(){
   if(confirm('Do you want to impersonate this user?')){
      top.location.href = 'ui_page_process.do?sys_id=b071b5dc0a0a0a7900846d21db8e4db6&sys_user='+ g_form.getUniqueValue();
   }
}

And here’s how you could modify Garrett’s solution above to create a UI Macro attached any user reference field in ServiceNow…

‘user_impersonate’ UI Macro
UI Macro icons require the creation of a UI Macro record under ‘System UI -> UI Macros’ (as shown below). They also require a dictionary personalization for the reference field the macro is associated with (as explained below).

Name: impersonate_user
Description:
‘Impersonate user’ link
Activate on any ‘sys_user’ reference field as follows:
– Set the active field in this macro to true
– Add the attribute to the reference field dictionary entry: ref_contributions=impersonate_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)" />
<g:evaluate var="jvar_admin" expression="gs.hasRole('admin')" />
<j2:if test="${jvar_admin == true || jvar_personalizer == true}">
   <j:set var="jvar_n" value="impersonate_user_${jvar_guid}:${ref}"/>
   <g:reference_decoration id="${jvar_n}" field="${ref}"
    onclick="impersonateUser('${ref}'); "
    title="${gs.getMessage('Impersonate user')}" image="images/icons/roleKey_obj.gifx"/>

   <script>
      function impersonateUser(reference){
         var referenceField = reference.split('.')[1];
         if(confirm('Do you want to impersonate this user?')){
            top.location.href = 'ui_page_process.do?sys_id=b071b5dc0a0a0a7900846d21db8e4db6$[AMP]sys_user='+ g_form.getValue(referenceField);
         }
      }
   </script>
</j2:if>
</j:jelly>

The post Direct User Impersonation From a User Record appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-actions-system-ui/direct-impersonation-user-record/feed/ 9
Adding Fields to the Service Catalog Checkout Screen https://servicenowguru.com/system-ui/adding-fields-service-catalog-checkout-screen/ https://servicenowguru.com/system-ui/adding-fields-service-catalog-checkout-screen/#comments Fri, 05 Nov 2010 14:07:44 +0000 https://servicenowguru.wpengine.com/?p=2635 I’ve written before about some customizations that can be made to the catalog checkout screen in ServiceNow. The catalog checkout screen gives users one last opportunity to review their order and provide some additional details about the overall request before submitting an order. One common customization request I’ve heard before is to add additional fields

The post Adding Fields to the Service Catalog Checkout Screen appeared first on ServiceNow Guru.

]]>
I’ve written before about some customizations that can be made to the catalog checkout screen in ServiceNow. The catalog checkout screen gives users one last opportunity to review their order and provide some additional details about the overall request before submitting an order. One common customization request I’ve heard before is to add additional fields to this checkout screen.

This article is an extension of an idea presented on the ServiceNow wiki that shows one way to approach this problem. The solution described here overcomes some of the problems with the wiki solution and gives a little bit more detail about how the solution works so that it’s easier for you to customize on your own. I’ll also include some formatting examples and show how you can add more than one additional field to the checkout screen.

This article describes an advanced customization that requires edits to an out-of-box UI Page and UI Macro. While it is possible (and often necessary) to make these types of edits, you should be aware that modifying these records prevents ServiceNow from upgrading them in the future.

 

Please note that in order to use this solution you must enable the two-step catalog checkout in your instance.

 

Add your new field(s) to the checkout screen

1Modify the ‘servicecatalog_cart_template’ UI Macro as follows…
Look for the section of code that has hidden input elements (designated by ‘input type=”HIDDEN”‘) and insert the following line directly after the other hidden elements. This line of code is used to store the unique cart ID for the user session. This ID will be referenced later on in a UI Page client script.

<input id="cart_id" name="cart_id" type="HIDDEN" value="$[sc_cart.sys_id]" />

Next, find the section of code that looks like this…


${gs.getMessage('Requested for')}:<label for="requestor_location">${gs.getMessage('Deliver to')}:</label>$[SP]
$[sc_cart.requested_for.getDisplayValue()]



<textarea id="requestor_location" style="width: 100%;" name="requestor_location" rows="4" wrap="soft"><br />
$[sc_cart.delivery_address]<br />
</textarea>$[SP]

And insert the following code directly below it. This sample code adds a ‘Company’ reference field to your checkout form. You’ll need to customize this code to add your own field(s).


Company:$[SP]
$[SP]

If you need to add multiple fields you can do so by adding the appropriate html. It’s also pretty simple to change the layout of the fields and their columns if you understand a little bit about html tables. Here’s an example that shows how to add two fields (Company and Requested Date) to the checkout form in a 2-column layout.


Company:Requested Date:$[SP]

$[SP]

You may have noticed the ‘ui_reference’ and ‘ui_date’ lines in the code above. These lines actually reference UI Macros by those names. The UI Macros are a great way to set up fields on a UI Page like this without having to set up all the specific pieces of the field element. There are several UI Macro field elements you can utilize out-of-box. These can be found by searching the UI Macros table for elements that start with ‘ui_’.

 

Passing the field values to the catalog cart and request

2Add the following script to the ‘Client Script’ field on the ‘servicecatalog_checkout_one’ UI Page (note that this sample is for the 2-field checkout addition and you’ll need to modify this script on the ‘var newField1’ and ‘var popVal’ lines if you’re only using one field). Its purpose is to get the values from the new checkout fields as they change and send them to the request ticket when the request is generated. You’ll want to pay attention to the separators used here to designate when a new field/value pair starts. The underlying code reserves some characters in this situation so I made a judgment call based on what I thought would work most of the time. The bottom line is that these need to match what you look for in the business rule in the next step.

If you need to add additional fields to your checkout page you’ll need to customize this function to include those additional field/value combinations.

function setCartValue() {
var fieldSeparator = '^'; //Cannot be ':' or '='
var nameValSeparator = 'IS'; //Cannot be ':' or '='

//Get the new field elements we've added
var newField = gel('core_company');
var newField1 = gel('requested_date');

//Query for the user cart
var cart_item = new GlideRecord('sc_cart_item');
cart_item.addQuery('cart.user', g_user.userID);
cart_item.addQuery('active', 'true');
cart_item.query();

//If found, add the field/value pairs to the 'hints' parameter for the cart
if(cart_item.next()) {
//Aggregate all of the field-value pairs
var popVal = 'company' + nameValSeparator + newField.value + fieldSeparator + 'requested_date' + nameValSeparator + newField1.value;
//Send the values to the request record
cart_item.hints = "";
cart_item.update();
}
}

If you’re just adding a single field to the checkout page (and have no plans to potentially add more fields) then you could simply modify the script above to eliminate the ‘u_cartpop’ and ‘popVal’ pieces all together. These pieces exist for the sole purpose of passing multiple field/value pairs on to the request. If you just need a single field, comment out the first ‘popVal’ line, change ‘u_cartpop’ to the name of the field on the request form you need to populate, and use the single field example included in step 1 above.

If you are looking for a more extensible solution that you could add to in the future, or if you already know that you will need more than one field added to the checkout form, read on!

Populating the field values

—This final portion is the major piece that I’ve changed from the solution described on the ServiceNow wiki. The whole purpose of these last steps is to allow you to populate more than one field on the request ticket. The ‘hints’ parameter in the UI Page client script above only accepts a single name/value pair to set. To work around this limitation, the script above concatenates all of the name/value pairs and passes them in as a single string to a custom field you need to create called ‘CartPop [u_cartpop]’.

3Create a new string field on the Request [sc_request] table named ‘CartPop’.
The field will be used to capture the field/value pairs string being passed from the checkout page. It should have a length that is long enough to accommodate all of the field/value pairs being passed in from your checkout page. A 1000 character limit should be more than enough to pass in values from several additional fields. This field can be removed from the request form once it is created.

4Create a new business rule on the Request [sc_request] table with the settings as shown below. The purpose of the business rule is to get the value of the ‘u_cartpop’ field, parse the field/value pairs out of it, and populate those values into the correct field(s) on the request record.

Populate Cart Values Business Rule
Name: Populate Cart Values
Table: Request [sc_request] When: before
Insert: true
Condition: !current.u_cartpop.nil()
Script:

//Get the values to populate and split into name/value pairs
var popVals = current.u_cartpop.split("^");
for(x in popVals){
//Split each pair and populate the correct field
var popVal = popVals[x].split("IS");
if(popVal.length == 2){
eval('current.' + popVal[0] + '="' + popVal[1] + '";');
}
}

If you’ve done everything correctly you should be able to order a catalog item, view and populate your new fields on the checkout form, and see those fields populated on the Request record as shown here…

Validating checkout fields / Making checkout fields mandatory

One last step that you may need to take is to make sure that certain checkout fields are filled out or validated before submission. I’ve written about how to do this in a separate article found here.

The post Adding Fields to the Service Catalog Checkout Screen appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-ui/adding-fields-service-catalog-checkout-screen/feed/ 34
Mandatory Fields on Service Catalog Checkout Form https://servicenowguru.com/ui-macros/mandatory-fields-service-catalog-checkout/ https://servicenowguru.com/ui-macros/mandatory-fields-service-catalog-checkout/#comments Thu, 18 Feb 2010 14:22:47 +0000 https://servicenowguru.wpengine.com/?p=985 If you’ve used the two-step catalog checkout before you’ve noticed the few fields on the final checkout screen. Users can provide information about the Requester and their location, along with some special instructions for the processing of the request. These fields are all optional however, so there’s no way to force a user to fill

The post Mandatory Fields on Service Catalog Checkout Form appeared first on ServiceNow Guru.

]]>
If you’ve used the two-step catalog checkout before you’ve noticed the few fields on the final checkout screen. Users can provide information about the Requester and their location, along with some special instructions for the processing of the request. These fields are all optional however, so there’s no way to force a user to fill any of this information out. If you did need to force one or more of these fields to be mandatory, you could accomplish this by making a couple of modifications to the ‘servicecatalog_cart_template’ UI Macro.

Service Catalog Checkout Man Field


Because we’re working in the Service Catalog interface, making a field mandatory will work a little bit differently than in other places in the system. For this modification we will intercept the submission of the form and check each field to see whether it is empty or not. This can be done by making changes to the following lines in the ‘servicecatalog_cart_template’ UI Macro.

This solution requires a modification to an out-of-box UI Macro. While it may be necessary or desirable in your environment, just be aware that once you modify it, you own it! ServiceNow doesn’t upgrade (but will support) records updated from their out-of-box config.

–In the ‘servicecatalog_cart_template’ UI Macro, change the onClick event of the submit button in this line…

<button id="sysverb_insert" class="catalog catalog_next" type="submit" value="sysverb_insert">

to this…

</button><button id="sysverb_insert" class="catalog catalog_next" type="submit" value="sysverb_insert">

–Note that in Eureka instances of ServiceNow you’ll be changing this line…

<a class="request_catalog_button" href="#" type="submit">

to this…

</a><a id="sysverb_insert" class="request_catalog_button" href="#" type="submit">

–Add the ‘checkMandatorySubmit-CatalogCheckout’ global UI script function by navigating to ‘System UI -> UI Scripts’. You can modify this function to check any field(s) on the checkout form.

This UI Macro script can be pasted directly into the ‘servicecatalog_cart_template’ UI Macro to make the ‘Special Instructions’ field mandatory on checkout.

‘checkMandatorySubmit-CatalogCheckout’ global UI script
Name: checkMandatorySubmit-CatalogCheckout
Script:

function checkMandatorySubmit(){
var manFields = '';
var si = gel('special_instructions').value;
if(si == ''){
manFields = 'Special Instructions';
}
if(manFields == ''){
gsftSubmit($('sysverb_insert'));
}
else{
alert('The following mandatory fields are not filled in: ' + manFields);
return false;
}
}

Here’s another example UI script that makes the ‘Requested for’ field mandatory for ‘ITIL’ users.

‘checkMandatorySubmit-CatalogCheckout’ global UI script
Name: checkMandatorySubmit-CatalogCheckout
Script:

function checkMandatorySubmit(this){
var manFields = '';
var si = gel('sc_cart.requested_for').value;
if(si == ''){
manFields = 'Requested for';
}
if(g_user.hasRole('itil')){
if(manFields == ''){
gsftSubmit($('sysverb_insert'));
}
else{
alert('The following mandatory fields are not filled in: ' + manFields);
return false;
}
}
else{
gsftSubmit($('sysverb_insert'));
}
}

The post Mandatory Fields on Service Catalog Checkout Form appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/ui-macros/mandatory-fields-service-catalog-checkout/feed/ 31