TUESDAY, FEBRUARY 07, 2012

Adding a UI Macro to a Non-reference Field

As of the Winter 2011 release, this technique is no longer necessary. If possible, you should use the ‘field_decorations’ attribute to point to the UI macro for the field. This post may still be useful for those on running instances on a release earlier than Winter 2011. The client script technique for adding UI macro field decorations may still be preferable in certain situations.

S

ervice-now reference fields allow you to add custom UI macros (which generally appear as icons) next to the input element for the field. A couple of common out-of-box examples of this are the ‘Show related incidents’ macro next to the ‘Caller’ field on the incident form and the ‘Show CI map’ icon next to the ‘Configuration item’ field. The main problem with these are that they are ONLY available to reference fields. So, if you want to do the same thing against a choice or string field you’re out of luck.

There is a way around this limitation though using JavaScript DOM manipulation. In Service-now terms, you can add the equivalent of a UI macro to any non-reference field by creating an onLoad client script to add the icon and corresponding onclick (or other) event. Here’s a simple example of an onLoad client script that you could use on the Incident table to display a macro next to the ‘Number’ field.



function onLoad() {
   //Add a UI macro to a non-reference field
   //Set the name of the field in the 'field' variable
   var field = 'number';
   //Append the table name to get the field id
   field = g_form.tableName + '.' + field;

   try{
   //Create the image element and add to the dom
   var img = document.createElement('img');
   img.src = 'images/warning.gifx';
   img.alt='Custom macro';
   img.title='Custom macro';
   var link = document.createElement('a');
   if (navigator.appName == 'Microsoft Internet Explorer'){
      link.setAttribute('onclick', Function('doSomething()'));
   }
   else{
      link.setAttribute('onclick', 'doSomething()');
   }
   link.name='my_custom_macro';
   link.id='my_custom_macro';
   link.appendChild(img);
   document.getElementById(field).parentNode.appendChild(link);
   }
   catch(e){
      //alert('Error');
   }
}

//onclick event to fire when the image is clicked
function doSomething() {
   alert('You clicked me!');
}

Here’s another example of an onLoad client script that you could use on the Incident table to display a lock icon next to the ‘Category’ field. The lock icon will show/hide the ‘Subcategory’ field when it is clicked. You could use something like this to show/hide different elements with a click on the icon.

function onLoad() {
//Hide these fields by default
g_form.setDisplay('subcategory', false);

//Add a UI macro to a non-reference field
//Set the name of the field in the 'field' variable
var field = 'category';
//Append the table name to get the field id
field = g_form.tableName + '.' + field;

try{
//Create the image element and add to the dom
var img = document.createElement('img');
img.src = 'images/locked.gifx';
img.alt='Unlock Fields';
img.title='Unlock Fields';
img.id = 'customLock';
var link = document.createElement('a');
if (navigator.appName == 'Microsoft Internet Explorer'){
link.setAttribute('onclick', Function('toggleLockFields()'));
}
else{
link.setAttribute('onclick', 'toggleLockFields()');
}
link.name='lock_fields_macro';
link.id='lock_fields_macro';
link.appendChild(img);
document.getElementById(field).parentNode.appendChild(link);
}
catch(e){
//alert('Error');
}
}

//onclick event to fire when the image is clicked
function toggleLockFields() {
//Toggle the lock icon
var lock = document.getElementById('customLock');
if(lock.src.indexOf('images/locked.gifx') > -1){
//Show the hidden fields
g_form.setDisplay('subcategory', true);

//Change lock to 'unlocked
lock.src = 'images/unlocked.gifx';
lock.alt='Lock Fields';
lock.title='Lock Fields';
}
else{
//Hide all lock fields
g_form.setDisplay('subcategory', false);

//Change lock to 'locked'
lock.src = 'images/locked.gifx';
lock.alt='Unlock Fields';
lock.title='Unlock Fields';
}
}
I recently wrote a post describing the details of lock icon behavior throughout the tool. Check it out here!
Tags:  ,

Comments

Posted On
Mar 04, 2010
Posted By
Marc

Love this and use it instead of a UI Macro even on a reference field for a customer who wants to only show the icons if the user has a certain role, however, one little thing they asked is why they float all the way to the right before any values are populated, I wondered if this code could be manipluated so that the icon goes all the way to the left instead of at the end of the ui macros

I think it’s this line that is saying go sit on the end of the line, but is there a way to say sit at the front of the line?

document.getElementById(field).parentNode.appendChild(link);

}

Shame I can’t upload an attachment to show it even better so but mail me if you would like know more or see what I’m talking about. thanks!

Marc

Posted On
Mar 04, 2010
Posted By
Mark Stanger

You’re correct about the line that would need to be modified. I think you could get the result you are looking for on a reference field by replacing this…

document.getElementById(field).parentNode.appendChild(link);

with this…

var fieldParent = document.getElementById(field).parentNode;

var lookupIconSib = document.getElementById(‘lookup.’ + field).nextSibling;

fieldParent.insertBefore(link,lookupIconSib);

Posted On
Mar 04, 2010
Posted By
marc

works a treat, much appreciated!!

Posted On
Jul 07, 2010
Posted By
Jay Pandya

Hi, I’ve got a need for a UI Macro on the Change Reference (field) on a Change Task…I take it this will work for that too as Number is a reference field.

Posted On
Jul 08, 2010
Posted By
Mark Stanger

There is a different approach for reference fields (number is a string field by the way). You need to add an attribute to the dictionary of the field that you want to have the macro on. That attribute calls your UI macro. I don’t have this approach documented, but you could look at the ‘caller_id’ or ‘cmdb_ci’ fields on the incident table as an example.

Posted On
May 04, 2011
Posted By
mathew

hai sir i am having some diffulty in understanding the client scripting stuff

can to give a step by step approach for the second example

Posted On
May 04, 2011
Posted By
Mark Stanger

You should refer to the comments in the code for the steps taken and an explanation of the script. If you have questions about specific pieces of the code please post them and I’ll try to explain further.

Posted On
Jul 15, 2011
Posted By
Russell Miller

Hi Mark,

Love the site.

After much hair pulling I noticed something while trying to use the ‘field_decoration’ attribute…

It should actually be ‘field_decorations’ !!! I only worked this out as a hail mary attempt when I noticed that ref_contributions was a plural, and that it does not seem to work on journal fields (note the “most field types” mentioned in the wiki)

Big shout out to the SNC wiki for having it wrong ;) I’m attempting to have the SNC wiki changed at the moment. Thought I’d post here too as this is my first point of call for SNC insight.

Cheers

Posted On
Jul 15, 2011
Posted By
Mark Stanger

Great catch! You’ve probably guessed that the wiki article is exactly where I pulled that info. from. I’ve updated the post above with the change.

Leave a Reply


Notify me of followup comments via e-mail. You can also subscribe without commenting.

Latest Comments

  • Mark Stanger: This linkage all happens for you if you use the task survey plugin. You can look on the wiki for more...
  • Vineeth: I want a way in which if a survey is filled in by the user the response are stored in the survey response...
  • Mark Stanger: This functionality doesn’t connect to an FTP server. See this line in the post above…...
  • Mark Stanger: The report page is back-end XML so there’s no way to directly manipulate the behavior of that...