Welcome Login
Blog Photos Links

RSS Feed

Table Name field type and scoped applications

April 30, 2018, 8:47 am - James Farrer

I've run into an issue several times lately and wanted to make a note for myself and thought I'd share it at the same time since it wasn't easy to find in the documentation.

When using a Table Name field on a scoped table there is a restriction by default that only allows tables from the applications scope to be selected in the field. Every time I've used this type of field I've needed to show other tables, particularly Task tables.

The fix is a simple, though obscure, attribute that can be added to the field. 

To fix it:

  1. Go to the dictionary record of the Table Name field with the issue.
  2. Add a new attribute using one of the two main methods:
    1. Using the Attributes related list
      1. Click the New button in the Attributes related list.
      2. Select the "Allow public" attribute.
      3.  Set the value to true.
    2. Using the Attributes field in the Advanced View
      1. Add the following to attributes string with commas to separate the attributes if there are others present:

        allow_public=true

For the field I was working on I had the following to show all Task tables while excluding Task itself:

allow_public=true,​base_table=task,​skip_root=true,​base_start=true

Identify workflows where a group is listed

January 17, 2018, 4:43 pm - James Farrer

 Here's a script that goes through the workflow activity fields and prints out where the group is listed in workflows.

// Sys ID of the group that we're testing for
var group_id = "c4762f920fd0310066e76ab8b1050e58";

var group_gr = new GlideRecord("sys_user_group");
if (group_gr.get(group_id)) {
	gs.print("Querying workflows for group: " + group_gr.getDisplayValue());
}
var wf_var_value_gr = new GlideRecord("sys_variable_value");
wf_var_value_gr.addQuery("value", group_id);
wf_var_value_gr.query();
while (wf_var_value_gr.next()) {
	// Query for the workflow activity
	var wf_activity_gr = new GlideRecord(wf_var_value_gr.document);
	if(wf_activity_gr.get(wf_var_value_gr.document_key)) {
		if(wf_activity_gr.workflow_version){
			// Query for the workflow version
			var wf_version_gr = new GlideRecord("wf_workflow_version");
			wf_version_gr.addQuery("sys_id", wf_activity_gr.workflow_version);
			wf_version_gr.addQuery("published", true);
			wf_version_gr.query();
			if (wf_version_gr.next(wf_activity_gr.workflow_version)) {
				gs.print("Group is assigned to " + wf_version_gr.name + " -> " + wf_activity_gr.name);
			} else {
				//gs.print("WF version not published " + wf_activity_gr.workflow_version.getDisplayValue() + " -> " + wf_activity_gr.name);
			}
		} else {
			gs.print("Workflow activity version is blank for " + wf_activity_gr.name);
		}
	}
}

ServiceNow Formatted Text (HTML WYSIWYG) editor

January 24, 2017, 2:54 pm - James Farrer

Editing formatted text in a web browser has come a long way over the years. This is true within ServiceNow as well. In general it's pretty easy to write a knowledge article and format things the way you want. Unfortunately there's a gap between just formatting it the way you want and having consistent formatting across the entire knowledge base, system, and self-service portals.

A lot of what I do is work with the CMS and now Service Portal within ServiceNow. If you don't know these are the sections of the tool that allow for creating a branded portal for end-users to interact with IT and other areas of the business support side of things. 

When you're working on a portal you build out the blocks, widgets, lists, menus, etc. and from the overall structure perspective you're in control. But as soon as you introduce the knowledge base and the articles that are created by anyone and everyone, consistency tends to go out the door. 

The default editor for formatting text in an article (and elsewhere in ServiceNow) is used and offers options for selecting the font, font size, bold, italics, underline, etc. This works ok if you're looking at all of the content in one place, but when you start to look at styles across articles and compared to other places in the self-service portal this starts to cause problems. Any good portal is going to come with a decent set of default styles for headings, paragraphs, links, etc. But the default editor options don't include any way to tie into these unless you are an HTML wizard and can edit the source.

Fortunately, there is a system property that allows us to add the common HTML tags that allow us to use these standard formats. The glide.ui.html.editor.v4.toolbar.line1 property contains the list of options available in the editor. I strongly suggest adding in the formatselect option with gives the Paragraph and Heading options so users can select a title and the various section headers and apply formatting automatically that will be consistent across the site.

The property can be found under System Properties -> UI Properties.

 

After you've got the property updated, a little bit of training to help the big contributors to start using it and your site should start to have a much more consistent look and feel.

Service Portal missing panel styles

December 13, 2016, 10:44 am - James Farrer

In ServiceNow and Service Portal there are some great features in a lot of places. There are, however, a number of rough edges since it's still pretty new. One of the places that I've found is a little rough is with the CSS. Many of the default widgets delivered by ServiceNow use the bootstrap panel structure. This gives a pretty nice format for setting up blocks with headings.

The problem is that most of the brand colors are not supported. It instead uses the default Bootstrap colors. The solution to this is to add the following styles to the widget CSS. It could also be added to the page CSS if you don't want to modify the widget. 

This code utilizes the brand colors set in the Branding Editor to apply the colors.

/* add styles to support brand colors in basic panels */
.panel-danger > .panel-heading {
    color: $panel-bg;
    background-color: $brand-danger;
    border-color: $brand-danger;
}
.panel-warning > .panel-heading {
    color: $panel-bg;
    background-color: $brand-warning;
    border-color: $brand-warning;
}
.panel-success > .panel-heading {
    color: $panel-bg;
    background-color: $brand-success;
    border-color: $brand-success;
}
.panel-info > .panel-heading {
    color: $panel-bg;
    background-color: $brand-info;
    border-color: $brand-info;
}

"Your" vs. "My" and interacting with the user

November 16, 2016, 2:33 pm - James Farrer

If you're building a self-service website, when dealing with the stuff relating to the user, you should most definitely use "Your" not "My".

I've done a lot of work in the self-service side of ITSM over the years. Much of this has been with ServiceNow as the environment. I've also dabbled in various levels of web development and interface design. A very common mistake and point of argument is that the menu link should be "My [stuff]". I'm not sure where this got started but I'm guessing it has something to do with wanting to make people feel at home and in control of the situation when dealing with a website. Either that or someone was lazy and just not thinking things through.

When I am dealing with a website me, my stuff, my computer, etc. is on my side of the network connection. The company, website, forms, information, etc. is another entity that I am having a dialog with. 

Flip that around and as a website developer I'm creating the dialog between the organization or company I represent and the end user. This means that when I'm giving instructions I will say "Here's what you need to do..." and anything that discusses the organizations thoughts, interests, etc. should take a first person narrative of "we", "us", "our", or in the case of a personal blog or something like that, "I", "me", and "my". 

I ran into a page today where I realized there was a sentence explaining how something works with "you can go to...and this is where you'll find...". Right below that there was a block label "My Approvals" where the approvals of the end user, not the organization, can be found. It seems like a pretty minor thing and enough websites have flip-flopped with these that most people aren't going to think too much of it but somewhere in the back of their mind something is going to be saying "hey, something is not quite right here". 

As an example of a site that has done this the right way, check out Amazon and their numerous links to "Your Account", "Your Orders", etc.

On a somewhat related note, I've also heard discussions on what form to put documentation for a system into. Should it be first person? Or perhaps an awkward neutral set of instructions that's cold and strictly business? This one often isn't quite as straight forward but I always appreciate the information that's written as more of an honest dialog that clearly articulates who is talking and who is listening. Making things a little more personal in a formal business world can often ease a little stress of a situation since it's just more natural.

So to sum it all up, here is my post that will hopefully persuade you to make your sites better at telling me when there is stuff relating to me with a link titled "Your stuff". Just to be as clear as mud.

 

Javascript in Helsinki - ECMA3 vs ECMA5

May 27, 2016, 1:51 pm - James Farrer

I was pleasantly surprised to hear that ECMA5 will now be supported in the Helsinki release of ServiceNow. For most people this won't mean much of anything. I was excited to hear about the change since there were a few things I had noticed missing when working with server side javascript. Most notably the indexOf operation on arrays.

Today I was testing out some functionality in Helsinki and ran into a really ugly error with something that worked perfectly fine in Geneva. 

After a little digging I discovered that the format for JSON was updated as well and is more strict now. So if you're doing any parsing of JSON in ServiceNow, make sure your property names use double quotes instead of single quotes and you'll save yourself some trouble. 

As an example, this:

{'incident':'caller_id'}

is incorrect. Instead you should use this:

{"incident":"caller_id"}

Simple Variable Summary

January 13, 2016, 2:52 pm - James Farrer

 I ran into a problem today where I needed a summary of requested item variables to send out in an email notification. I didn't see a good script for doing it but found a number that were close. Here's my version that does some checking to only show variables that would normally have content suitable to a summary. I'm sure there's room for additional improvement but for the time being this did the trick:

function printVariableSummary(){

   // Variable types that shouldn't be shown

   hidden_types = {

      12:true,

      20:true,

      24:true,

      19:true,

      11:true,

      14:true,

      17:true,

      25:true,

      15:true

   };

   template.print('<strong>Item Options</strong><br/>');

   var set = new GlideappVariablePoolQuestionSet();

   set.setRequestID(current.sys_id);

   set.load();

   var vs = set.getFlatQuestions();

   // Go through all the variables

   for (var i=0; i < vs.size(); i++) {

      // Skip variables without a label or that are a type that should be skipped

      if(vs.get(i).getLabel() != '' && !hidden_types[vs.get(i).getType()]) {

          template.space(4);

          template.print('     <strong>' +  vs.get(i).getLabel() + ":</strong> " + vs.get(i).getDisplayValue() + "<br />");

      }

   }

}

printVariableSummary();

Retina Icons in ServiceNow

December 2, 2015, 10:41 am - James Farrer

This is mostly for my personal reference but here is the info on what icons are available as taken from the ServiceNow Community Forum. Thanks to Shahid Shah for putting this out there.

 

What I can advise you is that the symbols are based on Web Fonts (in this case retina_icons) and the styling is managed in the internal CSS. So you are restricted to the available character set by using the icon-name format for the class name:

<i class="icon-name"></i>

 

Example icons are:

icon-cart

icon-catalog

icon-edit

 

To get a good idea on the available icons you can check out this sample page by replacing "instancename" with the name of the instance you're on:

https://instancename.service-now.com/styles/retina_icons/retina_icons.html

 

The CSS that provides these is here:

https://instancename.service-now.com/styles/retina_icons/retina_icons.css

 

Generate a GlideRecord Query for a List

August 12, 2014, 8:55 am - James Farrer

Have you ever wanted to just get a quick GlideRecord Query for a list you're looking at? I've wanted to do that many times. Sometimes it's because I'm writing a business rule and sometimes I've got to run a background script to update some values. 

I finally took a couple minutes and put together a rather simple script that does just that. 

To set it up in your instance go to System UI -> UI Context Menus and open a new record. The other values should be as follows:

Table: Global

Menu: List Header

Type: Action

Name: Get GlideRecord Query

Condition: gs.hasRole('admin')

Order: 2000

Action script:

// Check for a query from the related list
var rel_list_prefix = '';
try{
	if(g_form != undefined){
		var field_name = g_list.getRelated().split('.')[1];
		if(field_name != undefined){
			var sys_id = g_form.getUniqueValue();
			rel_list_prefix = field_name + "=" + sys_id + "^";
		}
	}
} catch(e) {}

// Generate the query
var query = "var gr = new GlideRecord('" + g_list.getTableName() + "');\n";
query += "gr.addQuery('" + rel_list_prefix + g_list.getQuery() + "');\n";
query += "gr.query();\n";
query += "while(gr.next()) {\n";
query += "	\n";
query += "}";
alert(query);


Now that you've got this, from any List you can right-click on the header and the bottom option will be "Get GlideRecord Query" and you can copy the resulting code. It's nothing complicated, but can still save a bit of time.

The key to making this work is the g_list object that has the details for the list that you're on. It's documented fairly well on the ServiceNow Wiki and if you haven't seen it before I'd recommend glancing at what options are available.

Client Side Dates in ServiceNow

February 18, 2014, 9:13 am - James Farrer

TL;DR

I keep coming back to this post for specific tidbits so I decided I would put the key code snippet right at the top to make it easy. Basically, to get a javascript date from a ServiceNow date field value do this:

var date_number = getDateFromFormat(g_form.getValue('the_date_field'), g_user_date_format);
var my_date = new Date(date_number);

Or, from a Date/Time field do this:

var date_number = getDateFromFormat(g_form.getValue('the_date_time_field'), g_user_date_time_format);
var my_date = new Date(date_number);

 

The Long Version

Working with dates on the client side of things in Service-Now has always been a challenge. Part of this is just due to Javascript and the challenges associated with dates and the other is ServiceNow. Given that users can have their own date format makes it even more challenging. That said, we are given some tools (albeit undocumented ones) that can help improve the situation.

I ran across some information (thanks to John Roberts) that helps the situation drastically. The key comes down to a couple global variables defined by the system and a function provided that helps use those variables. 

The variables give us the date and datetime formats for the logged in user, and the function lets us use those to get something we can work with a little easier.

User datetime format:
g_user_date_time_format
 
User date format:
g_user_date_format
 
These used with the getDateFromFormat function gives us an easy way to get a value for the date (essentially a Unix Timestamp). That value can then be used directly or immediately passed into a Javascript Date object to allow for reformatting, testing, or whatever else is needed.
 
Here are a few functions that I put together to simplify the date validation process that is so often needed.
 
Test for valid DateTime based on user format:
function isValidDateTime(value){
    if(value == '' || value == undefined || value == null){
        return false;
    }
    return(getDateFromFormat(value, g_user_date_time_format) != 0);
}
 
Test for valid Date based on user format:
function isValidDate(value){
    if(value == '' || value == undefined || value == null){
        return false;
    }
    return (getDateFromFormat(value, g_user_date_format) != 0);
}

 

To take this a step further, you could easily add comparisons of dates or add custom date formats based on the values.

One thing to keep in mind with this, depending on where the date is coming from you may still have two date formats. Any of the dates that will work as shown are going to be the values in fields on a form or the Display Value of the date. If you're getting something from the server (e.g. via GlideAjax) as just a value then it will be stored in the regular system format of YYYY-MM-DD HH:MM:SS.

Hopefully this helps save you some of the frustration I've experienced over the years.


What's New

There are currently no new items, please check back later.

Archives
2018 (2)
  April (1)
  January (1)
2017 (1)
  January (1)
2016 (4)
  December (1)
  November (1)
  May (1)
  January (1)
2015 (1)
  December (1)
2014 (2)
  August (1)
  February (1)
2013 (4)
  October (1)
  July (1)
  June (1)
  April (1)
2012 (11)
  December (2)
  October (3)
  September (1)
  May (1)
  April (1)
  February (2)
  January (1)
2011 (14)
  December (1)
  November (1)
  September (2)
  July (2)
  June (1)
  May (1)
  April (2)
  March (3)
  January (1)
2009 (2)
  October (1)
  June (1)
2008 (1)
  September (1)