Skip navigation




Assumes basic knowledge and/or familiarity of scripting in ServiceNow.




So, this isn't a code snippet article, but rather a set of links to some of my favorite resources.  I hand these out to every ServiceNow Scripting class that I teach, so I thought they might be useful here as well.








4 javascript courses.  It will take you to advanced.  Covers best practices with JavaScript.   You-tube AND hands on.  $29/mo.  However, 1st of the 4 is free.

Also Regular Expressions (new!): Level one is free

Free, no videos, but hands-on labs.  Will take you up to intermediate.



Javascript the Good Parts by Douglas Crockford

JavaScript: The Good Parts - O'Reilly Media


Secrets of the JavaScript Ninja  by John Resig

Manning: Secrets of the JavaScript Ninja


You Don't Know JS series you don't know js: Books


Object Oriented Programming (sort of.  Well this is JavaScript we are talking about here!)

The Principles of Object-Oriented JavaScript: Nicholas C. Zakas: 9781593275402: Books



Differences among scripts article


Glide Class


Glide Record


Glide System

Glide Element


Application Scoping

Scoped GlideUser API Reference - ServiceNow Wiki


Funny JavaScript Video (yep, there is such a thing - thanks mamann!)




Steven Bell



For a list of all of my articles:  Community Code Snippets: Articles List to Date

This best practice article offers practical guidelines for debugging in Fuji. Jam-packed with useful information, it includes two videos that detail the new debugging features in the ServiceNow Fuji release, as well as the best ways to optimize instance performance. The new methods in Fuji provide you with consistent control over how your application manages debugging output in terms of verbosity – or what's logged – and the destination where it's logged.


debug part 1.jpg


The new custom applications recognize two properties. The first property, the verbosity, allows you to specify the verbosity of the output. The second property, the destination, allows you to specify the output destination.


Follow these debugging best practices to help you get started:

  • Create both destination and verbosity properties for your custom app in System Properties.
  • Create a Properties page for your custom app’s debugging properties.
  • Set your application’s default verbosity to error and the default destination to db.
  • Use the new Sequence field in the log list to sort entries accurately.
  • Use all methods appropriately.


Check out ServiceNow KB: Best Practices - Debugging in Fuji (KB0550844) for details on each best practice, as well as additional tips for debugging in Fuji to improve performance. Watch the videos for specific examples, or use the article as a quick reference for debugging successfully in Fuji. For a video demo of our best practices for debugging in Fuji see Best Practices for Debugging in Fuji Part 1 and Best Practices for Debugging in Fuji Part 2.


For more info about debugging, see:

Boosting the signal here.


poornachander wrote up a nice blog post on the different integration APIs available on the platform: ServiceNow Integration API Technology Stack


The only note I'd like to add is that if you're starting off something new, use the new REST API instead of JSONv2.  The new REST API is faster and more consistent with what one would generally expect from a REST interface.  And it works with the REST API Explorer tool too.  JSONv2 isn't going away, but going forward the emphasis will be on the REST API.

In ServiceNow, records can store both date and time values in different types of fields. The default date and time formats are defined using properties accessible by navigating to System Properties > System. The values are stored in the database and displayed in date or time format.

The calendar icon calendar_icon2.jpg displays the date or date-time picker on date or date-time fields:


The calendar icon appears next to fields on many forms in ServiceNow.


Clicking calendar icon on date-time time when modifying a form:

There is an issue on Internet Explorer 9 and 10 when modifying a form and clicking on the calendar icon next to a date-time field. A dialog box displays asking "Are you sure you want to leave this page?"


There are two options:

  • Leave this page
  • Stay on this page

Choosing either option does not affect the form.



This issue is seen in:

  • Fuji Patch 1
  • Fuji Patch 2 - Hot Fix 1
  • Fuji Patch 3
  • Fuji Patch 5
  • Eureka Patch 2


To resolve the issue, upgrade to Fuji Patch 6 or a ServiceNow version listed in the Fixed In field on the knowledge base article explaining the issue (KB0550055). You can also subscribe to the article for updates made to the workaround section or Fixed In and Seen In fields.


Additional information:

I get asked about this a lot:  How do I get local time out of GMT (Greenwich)?  OR  Why is my day of week calculation not working???


Here is an example of how to obtain the corrected (from GMT) local day-of-week:


TEST: Expected results:  Day-of-week: 4.  Without the local offset it would be 3 (nasty GMT!).


var startDateTime = "2015-04-30 01:00:00";  // my example is in GMT


// The following returns the GMT date time object (converted from the string value). 

// So next step is to get the local offset and add it to GMT

var gmtDateTime = new GlideDateTime(startDateTime); 


// getTZOffset is returned in negative milliseconds...

// so you have to get rid of that (I suppose you could use Math.abs)

var correctedOffset = new GlideTime(gmtDateTime.getTZOffset() * -1);  // the secret sauce


// NOW you can add the corrected value to the original gmtDateTime

gmtDateTime.add(correctedOffset);  // adds the milliseconds value to the gmt date/time object


// true local day of week value

var dayOfWeek = gmtDateTime.getDayOfWeek(); 


Painful, true, but it gets the correct value for local day-of-week.


Millisecond Converter


So, in the same vein, another handy/quick conversion to get days from milliseconds is:


var millConvert = 24 * 60 * 60 * 1000;  // hr, min, sec, milliseconds

var millisecondsExample = 604800000;  // 7 days expressed in milliseconds

var getDaysFromMilliseconds = millisecondsExample / millConvert;  // you get 7


Remember ye old programmer axiom:  Date/Times are evil!


Steven Bell


P.S. I would be curious to know if anyone has a faster/neater/cheaper method for the date/time correction!  Date/Time handling is always a super contentious topic of discussion so your responses are welcome! :-)


Trailing the trailing space

Posted by Slava Jul 22, 2015

Extra spaces are clearly one of those nightmares of the IT world that continually haunt end users as well as admins and developers. While surfing the web, have you ever come across ugly hyperlinks with underlining stretching beyond the link text? Or have you ever been unable to log in to an application because you overlooked a trailing space when copying the password from an email? Or maybe you happened to waste a few hours debugging your app because of an extra whitespace character in the value of a string variable that went unnoticed?


Now that these examples have hopefully evoked some reminiscences, let us get down to the business of banishing unwanted spaces from your ServiceNow instances. It goes without saying that the golden rule for any development is of course to cleanse the data before putting it into the database. In ServiceNow, this is easily achievable through a before business rule:


current.field_name = current.field_name.trim();


It takes almost no time to create a rule that can save you hours of troubleshooting headache later on!


Preventive measures are never a bad thing but the question you are likely to ask is: "What if I wanted to check if extra spaces have already found their way into my ServiceNow instance?"


Indeed one cannot search for a whitespace character using list search in a regular way because – as you would naturally expect – ServiceNow follows the aforementioned golden rule and trims the input before executing the search. So in this case – strange as it may sound – we will have to work around a best practice. Luckily list search supports the use of JavaScript. Thus if you wanted to find all records in a table with a trailing space in, say, Name field, you could simply select that field in the Go to box and search for:


%javascript:' ';


Note the usage of the % character as a wildcard in this example. Alternatively you could build the following condition in the list filter to achieve the same result:


     Name – ends with – javascript:' ';


As you can see, the trick is very simple and leaves no space for undesired spaces in your ServiceNow instance. Moreover, the same technique can be used to find records with leading spaces or characters that have a special meaning for the search engine:


%javascript:'*';     // find trailing asterisks
*javascript:'%';     // find records with % characters

Despite the fact that this feature was made available in the new Fuji release to the Administrators, creating database indexes via the User Interface has been in the ServiceNow platform for a long time. Before the Fuji release, it was only available to and was only used by ServiceNow staff that has the maintenance access – the super user role known as ‘maint’.


As your instance is supported by a traditional relational database management system (RDBMS), you will be able to apply some of your database optimization skills to fine-tune the ServiceNow instance. The ultimate goal is to improve the performance level on your instance. One of the most popular techniques to improve database performance is adding appropriate index to your table.


Now, users on the Fuji instances with 'Admin' role can have access to the ‘index creator’ module via two different paths:

  1. Follow these instructions to Add a Database Index
  2. Go to System Definitions >Tables and Columns, select the target table by clicking the table name in the list and the ‘index creator’ will be at the bottom of this page:

index creator servicenow.jpg


Before you get excited and submit the request, there are a few things to consider:

  1. This is an ADVANCED procedure and should only be performed by an administrator familiar with database management.
  2. The index is not created immediately. The next available system background worker thread will execute the request.
  3. Once the index has been created, you cannot remove it without asking ServiceNow Support team.
  4. Be careful of the ‘Use Unique Index’ option. WARNING: creating a UNIQUE index in the UI could lead to data loss if the data on the selected columns are not unique.
  5. Is there another index that already exists for the target column? If so, reevaluate.


Once you have considered everything and determined a new index will help to speed up the reading of data from the Database. You can implement it in minutes:

  1. Select one or more columns to index.
  2. Specify a unique Index Name.
  3. Click Create Index. The 'Create a New Index' dialog appears.
  4. Enter your email address in the Email me field (recommended), or select Do not notify me.
  5. Click OK.



After you click OK a few things will happen.  First, a background job will be put in the system jobs queue waiting for the next available worker thread. Once the job starts to execute, a temporary table will be created and altered with the new table definition. This will create triggers to propagate any changes on the live table into the temporary table. The data will then be copied from the live table into the temporary table in small chunks and will swap the temporary table with the live table. Once this occurs, the triggers drop. Finally, if necessary a notification will be sent to the nominated email address.


Over the years, I have recognized a few best practices and recommendations of my own.


Best Practices for creating Database Indexes via the user interface:

  • Design your index together with your tables. Don’t wait until there is a performance issue.
  • Consider the fact that index only speeds up reading from the database at the cost of slowing down writing operations.
  • In some cases a bad index can be worse than no index at all on the table.

So, since joining CloudSherpas, I have been writing articles on their/our blog sites (Scripting 101, Discovery 101, Admin 101), and have been neglecting my old blog here.  I have been thinking on a line of short articles that would be useful to community members.  So here you go! 


Javascript Switch Statements - A useful alternative to infinite if/then/else if/else statements!


I see this a lot in code scripts:  A run-on if (...) {} else if (...) {} statement.  While they have their uses (especially with mixed variable checks); they can be confusing to a maintenance coder (even if well commented).  Might I suggest that if you find yourself faced with the need for a large if/then statement that examines the same variable that you use a 'switch' statement instead.  With this sort of situation; 'switch' statements can organize the code in a more maintainable manner, and allow for easier condition additions at a later time.


Here is an example.  First the if/else if, and then the same thing re-written as a 'switch' statement:


// If/then/else if/else

var myCheck = 'yellow';

var temperature = '0 F';


if (myCheck == 'green') {"(if) All is well with the 'verse!");

    temperature = '72 F';


else if (myCheck == 'yellow' || myCheck == 'yellow-orange') {'(if) The Dallas Cowboys really reside in Arlington.');

    temperature = '85 F';


else if (myCheck == 'orange' || myCheck == 'orange-red') {

    if (myCheck == 'orange') {'(if) Temperatures in Dallas are hotter than in Houston, and the humidity is worse!!!');

        temperature = '95 F';


    if (myCheck == 'orange' || myCheck == 'orange-red') {'(if) Wait, it is hotter than I thought!!');

        temperature = '98 F';



else if (myCheck == 'red') {'(if) Red alert!  Red alert!  Danger, danger Will Robinson!');

    temperature = '100 F';


else {'(if) I have no idea what the myCheck value means!');

    temperature = '>100 F!';

}'(if) The temperature is: ' + temperature);


// switch analog

switch(myCheck) {

    case 'green':"(switch) All is well with the 'verse!");

        temperature = '72 F';


    case 'yellow':

    case 'yellow-orange':'(switch) The Dallas Cowboys really reside in Arlington.');

        temperature = '85 F';


    case 'orange':'(switch) Temperatures in Dallas are hotter than in Houston, and the humidity is worse!!!');

        temperature = '95 F';

    case 'orange-red':'(switch) Wait, it is hotter than I thought!!');

        temperature = '98 F';


    case 'red':'(switch) Red alert!  Red alert!  Danger, danger Will Robinson!');

        temperature = '100 F';


    default:'(switch) I have no idea what the myCheck value means!');

        temperature = '>100 F';


}'(switch) The temperature is: ' + temperature);


Notice that with the 'switch' it is a simple matter to add new conditions ('else if') by inserting a new 'case' statement.  If you want to add an 'OR' into the mix simply add a new 'case' condition before the code you want executed (yellow OR yellow-orange).  The 'default' statement acts as the catch-all (the same as the 'else' statement in the 'if/then' structure).  BTW, the 'default' statement is optional (the same as the 'else' is optional in the 'if/then/else' statement).  Don't forget the 'break' statement as this serves to keep the program from executing the lines immediately following!  Try out the 'orange' value to see what I mean.


I suggest if you are curious to see how this all runs you can play with it in a Fix Script or in Scripts - Background (you will need to raise your security to Security Admin).


There you go!  Another tool for your toolbox.



If you are working in a split layout and have a choice list value that uses more than one word in an URL argument (for example, category is System Software as opposed to Software) you can oddly end up with a %20 between words in Chrome and Firefox. Here’s what you’ll see:


Screen Shot 2015-01-28 at 12.25.53 PM.JPG



To resolve this issue, you can use one word, or better yet, create an onLoad client script on the table using the script value below:


  1. Right-click on the table header, and select Personalize.
  2. Select Client Scripts.
  3. Create New.
  4. Select OnLoad for Type.
  5. In the Script field, enter the script:


if (g_form.getValue('FIELD_NAME') == 'WORD1%20WORD2') {

g_form.setValue('FIELD_NAME','WORD1 WORD2');



Just replace the FIELD_NAME, WORD1, and WORD2 values with the appropriate field name and multi-word values, and you’ll be off and running at 100%.


Screen Shot 2015-01-28 at 1.45.43 PM.JPG


Have other quirks with layout or spacing? Here are some other articles to help you out:

At ServiceNow we have users all over the world, in different time zones, where, strangely enough, they do things like put the day in front of the month. So we understand that there are times when the default date and time format is not going to work for you. The format in which dates and times appear depend on the Date/Time setting. In the UI15 banner frame, click the gear icon compact_date_time1.jpg to view and edit Date/Time settings.



If you select the Compact list date/time option, the following is not shown with the date in list views:

  • year (for date values within the current year)
  • seconds

The Compact list date/time option is not available if the Date/Time selection is Time Ago.


Compact list date/time option and time zone:

There is an issue where enabling the Compact list date/time option changes the time zone to Pacific Standard Time. The value is displayed correctly in compact format without the year and seconds, but the time is shown in Pacific Standard Time. If you change the setting back to normal (non-compact) view, the value is once again shown in the user's time zone.


This issue is seen in:

  • Dublin Patch 7 Hot Fix 2
  • Eureka Patch 3 Hot Fix 1
  • Fuji
  • Fuji Patch 1
  • Fuji Patch 2 - Hot fix 1 and 5


To resolve the issue, upgrade to a ServiceNow version listed in the Fixed In field on KB0549988: Compact Date/Time changes the timezone to PST and subscribe to the article for updates made to the workaround section or fixed in and seen in sections.



Additional information:


Demystifying form tabs

Posted by Slava Jul 7, 2015

There are a few mysterious things in ServiceNow that are often believed to be out of administrators’ reach. These are various pieces of the core functionality that simply work the way they do. Tabbed forms are definitely one of them. In this post, I will show you how to deal with form tabs and teach you some tricks that you are not going to find in the Wiki.


Toggling tabs on/off is very well explained in this post by Mark Stanger. There are, however, a few other things you may want to do with tabbed forms. The table below gives an overview of methods and properties available to you in your client-side scripts:


Method / PropertyDescription
g_tabs2Sections.hasTabs();Returns true if the form has any tabs and false otherwise


or g_tabs2Sections.activated
Returns true if tabbed view is ON and false otherwise
g_tabs2Sections.deactivate();Switches tabs OFF
g_tabs2Sections.activate();Switches tabs ON
g_tabs2Sections.tabs.lengthReturns the total number of tabs on the form
g_tabs2Sections.activeTabReturns the index of the currently selected tab as a String
g_tabs2Sections.setActive(0);Takes tab index* as its argument and switches to the corresponding tab
g_tabs2Sections.hideTab(2);Takes tab index* as its argument and hides the corresponding tab
g_tabs2Sections.showTab(2);Takes tab index* as its argument and reveals the corresponding tab



Takes tab ID as its argument and hides the corresponding tab



Takes tab ID as its argument and reveals the corresponding tab



Takes tab ID as its argument and returns the index of that tab
g_tabs2Sections.findTabIndex(‘comments’);Takes a field name as its argument and returns the index of the tab that contains the field
g_tabs2Sections.hideAll();Hides all form sections (but keeps tabs visible if in tabbed mode)
g_tabs2Sections.showAll();Unhides all form sections (except those hidden using hideTab() method) and displays them one below another
g_tabs2Sections.markAllTabsOK();Hides the red mandatory field indicator from all tabs (indicators on individual fields remain)
g_tabs2Sections.markMandatoryTabs();Displays a red indicator on tabs that have mandatory fields
g_tabs2Sections.markTabMandatoryByField(‘comments’);Takes a field name as its argument and marks the form section that contains that field mandatory (but does not prevent saving the record if all mandatory fields are in fact filled in)


* Tab indices start at 0


Examples in this table use g_tabs2Sections object and therefore work with form sections. To manage related lists in a similar manner, use g_tabs2List object instead.


To give you an idea of how some of these methods can be used in a real life scenario, here is a script that enables switching between form sections using Alt+PageUp and Alt+PageDown combinations of keys:


addLoadEvent(function() {
   $$('body').each(function (elm) {
      Event.observe(elm, 'keyup', function(event) {
         if (g_tabs2Sections.activated && event.altKey) {
            var btnCode = event.keyCode ? event.keyCode : event.charCode;
            var tabsNumber = g_tabs2Sections.tabs.length;
            var currentTab = g_tabs2Sections.activeTab * 1;
            var nextTab = 0;
            if (btnCode == 33)
               nextTab = currentTab - 1;
            if (btnCode == 34)
               nextTab = currentTab + 1;
            if (nextTab > -1 && nextTab < tabsNumber)


You can use it in an onLoad client script for a specific table, say Task, or in a global UI script to enable this feature for all forms in your instance.

Have you ever asked yourself why your events are not being processed and your emails are not being sent? Generally, it can be very difficult to identify what is happening in these cases from a customer's perspective. The are a few reasons you may be experiencing this:

  • The event processor has been running for several hours and is possibly stuck.
  • The event processor has not been able to start.
  • The event processor is running for a long time but is actually processing a lot of events.
  • The event processor is running for a long time but is working on a rather big event, which could require the processing of various business rules or various records.


You can do some troubleshooting on your own to determine if the event processor has been unable to start although it has already been queued in the system scheduler.

servicenow event schedule.jpg

Troubleshooting the Events Processor and the Scheduler's Workers


1) Check the scheduled jobs to verify if the event processor has already been queued.

To do so, connect to the instance and go to System Scheduler > Scheduled Jobs > Scheduled Jobs. In this page, search for the "events process" job. Make sure that you can see the "state" column. If it shows as "queued," then the job has been scheduled to run by an available worker. This normally indicates that the Scheduler has a lot of scheduled jobs running and all of its workers are running jobs.


There is a second reason for the job to remain in "queued" state and it may be that it was running on a node when the node abruptly restarted. In this case, all that is


needed is to reschedule it by changing the state of the job back to "ready" and changing the Next Action value to something in the near future.


2) Check the stats page and xmlstats

If the "events process" job has been queued, you will want to check the stats page of the node you are on, and the xmlstats pages of the other primary nodes on the instance (you can reach this page from the Diagnostics page). In the stats page, look for the Background Scheduler and check if all the workers have a job assigned to them and what the value of "queue length" is. You can check the xmlstats page for similar information.


The reason for this is to see if there are long queues in the node schedulers. If the "queue length" is greater than 0, we can confirm that the scheduler has a lot of jobs scheduled and will take a little longer to complete. This often occurs when Discovery jobs are running contemporarily.


Next, check the xmlstats page. For example, you can search for "scheduler.queue.length" to verify how many jobs are queued up. It represents the value for "queue length" seen in the stats page. The same considerations made for the stats page can be made for the xmlstats page. If you look under "scheduler.workers" you will be able to see if the workers are executing jobs, just like in the stats page.


3) Check which jobs are taking a long time to run

If the above checks show that there are long queues on the scheduler in all nodes, you will need to check what jobs are taking a long time to run. Once you have identified the scheduled jobs that are running for an extended amount of time, you will have to decide whether to stop them or request Customer Support to stop them. Please note that you will be able to stop the long running scheduled jobs only on the node you have logged in to (i.e. the node where you see the stats page). If your long running scheduled jobs are on another node, you will need to request Customer Support to stop them.


In case your long running jobs are shown in the stats page, you can go to the All Active Transactions page (under User Administration > All Active Transactions). Make sure that you can see the "Uncancelable" and "Thread" columns. These will help you identify the long running job and if it is possible to cancel it. Should the "Uncancelable" field show true, then you will not be able to stop it yourself. To stop the job, select the checkbox next to the job (on the job's record) and under "Actions on selected rows..." choose "Kill." Please note that choosing "Delete" will not stop the job although it will make it disappear from the view.




As of Eureka, we have introduced the burst workers. These workers will allow high priority jobs (such as the events processor) to be prioritized and run no matter what queue there is in the scheduler. There is, however, a situation which can still impact these high priority jobs and have them not run in a timely fashion; this happens when the burst worker has become idle. This means that when the job finished, instead of closing off the thread, it has become blocked and is unusable. You can check if this is the situation by looking in your stats page to see if there is a burst worker without a job running on it. This will allow you to check on the node you have logged in to. For the other nodes, you can check the xmlstats page for the idle burst workers by looking for "burst.worker". Should you find one (or more) in the "scheduler.workers" tag, you will need to check if a job is currently running on it. If not, you will have an idle burst worker which will need to be checked by Customer Support.


If none of the above show that the events processor is queued waiting on a scheduler worker, then you probably are falling under another of the situations mentioned at the beginning of this article.

Composite fields are used in Demand Management and in Project Management applications and pull two types of information into a single field.

The idea for this blog post and the title were completely swiped from a Twitter post by community member, Robert Fedoruk (rfedoruk)!


A composite field combines information from two fields in a table to create one field. Composite fields are available in the following tables beginning with the Fuji release:

  • Project [pm_project]
  • Project task [pm_project_task]
  • Demand (dmn_demand]
  • Idea [idea]


Using composite fields in ServiceNow:

In the screenshot below, you can see the Dictionary Entry for the Idea column in the Idea [idea] table. The Type is a Composite Field and the Attributes field tells us that the first field is the Short Description and the second field is the Number.


Now, let's see the beautiful list view this creates. Here is the Ideas list with the Idea column showing both the Short Description and the Number fields. Click the number to open the Idea form. Note that the Demand column also contains a composite field with the demand Name and Number. (After an idea is accepted, it is promoted to a "demand.") Click a number in the Demand column to open the Demand form.


If you sort the column, sorting is based on the short description and not the number. For example, in the screenshot below I switched the sort order of the Idea column to ascending (a-z). Note that in the first two rows of the column, two ideas with empty short description fields show at the top, followed by two short descriptions beginning with a number (360), and then short descriptions beginning with the letter "A."


Composite fields are new in the Fuji release. Stay tuned for more information about composite fields in upcoming releases.


Additional tips and information:

Filter Blog

By date: By tag: