Welcome Login
Blog Photos Links

RSS Feed

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.

ServiceNow Workflow Join Activity

October 7, 2013, 6:30 pm - James Farrer

A few weeks ago I came across an issue involving a Workflow Join Activity and some confusion around what it does and how it works. There is a little bit of documentation on the wiki but it still left some questions unanswered.

The purpose of the Join Activity is to combine two or more paths of execution after they have branched out. This serves the purpose of ensuring that subsequent activities will not get run multiple times with unexpected results.

A Join activity will always wait for all active paths of execution to reach it before proceeding.

The difference between the Complete and Incomplete outputs comes down to whether or not all possible paths of execution have completed. For example, if there is a split to have two simultaneous tasks on parallel paths then after both tasks have completed the Join will finish with Complete.

To contrast that, when there is an if statement, only one path will ever actually get executed so the Join will always exit as Incomplete.

Hopefully that clarifies things a bit for you; it certainly helped me to review how it worked.

Remove invalid characters from a field in ServiceNow

July 1, 2013, 10:34 am - James Farrer

Over the weekend I helped with an issue that came up involving form validation in ServiceNow. I've seen this a few times so I thought I'd throw out a reminder to myself and others about it. The goal was to remove invalid characters from a field leaving only numbers. At first this seems pretty simple, just do a regex and set the new value.

It's really not much more complicated than that, but there is one more very important step to take. Since the code is running in an onChange client script if you just set the new value then it will cause the onChange to run again. This onChange will run even if the value hasn't changed.

The trick is to perform a simple check in the function for whether the updated string is different than the original and only updating the value if it has changed. In general this is a good practice that often gets overlooked.

Leaving it out will result in StackOverflow errors from an infinite loop of onChange calls.

Here's the client script code, just replace "your_variable_name" with your own and you should be on your way:

function onChange(control, oldValue, newValue, isLoading) {
    
    // remove invalid characters from field
    var clean_str = newValue.replace(/[^d]/g,'');
    
    if(newValue != clean_str){
        g_form.setValue('your_variable_name', clean_str);
    }
    
}

What's New

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

Archives
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)