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" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:evaluate var="jvar_guid" expression="gs.generateGUID(this)" /><j:set var="jvar_n" value="show_incidents_${jvar_guid}:${ref}"/>
<j:set var="jvar_n" value="show_ci_calendar_${jvar_guid}:${ref}"/>
<g:reference_decoration id="${jvar_n}" field="${ref}"
  onclick="showCIChangeCalendar('${ref}'); "
  title="${gs.getMessage('Show CI Change Calendar')}" image="images/icons/dayview.gifx"/>

<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>
</j:jelly>

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"><img src="images/icons/dayview.gifx" title="CI Change Calendar" alt="CI Change Calendar"></img></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);
   }
}

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