Tips & Tricks

Creating a simple ‘Record Count’ Service Portal Widget

When starting out in Service Portal with custom widgets, it’s a good idea to start out with a simple idea. AngularJS is the JS framework ServiceNow have chosen to use for the ServicePortal, if you haven’t used AngularJS before it probably worthwhile having a read up on it first. There are plenty of tutrials online to get you started and I’m sure there are many courses on Udemy / Lynda etc.

Back on the theme of starting out simple, the most simple thing I could think of was a replication of the ‘Single Score’ report available in the Reporting Application.

Things to think about
  • The widget options should allow the user to select the Table, define the query and set a title
  • The widget should look similar to the “Single Score” Report
The Widget Editor

The widget editor provided by ServiceNow is really intuitive and easy to use, enabling full development of a widget without even leaving the page. To open the widget editor, go to Service Portal > Service Portal Configuration > Widget Editor. If you’re following along with this article, you’ll want to click “Create a new widget”, in the modal window that appears give the widget a name of “Record Count”, The Widget ID should auto populate. Press submit to create the new widget. You will now be presented with the Widget Editor.

HTML Template – This is where we create design / layout for our widget. Note: you can use Bootstrap CSS classes in here, making designing really easy.
Client Script – For this example we don’t need to use any client script, but do not this is not a Client Script in the traditional ServiceNow sense, instead this is where we would write AngularJS code, a full list of the Service Portal Client Script API’s can be found in the ServiceNow Documentation
Server Script – Much like traditional ServiceNow Server Scripts with a few additional bits, we’ll come onto that later.

Creating the Record Count Widget

Hopefully you’ve read through all of the above and you are now sat waiting with a blank “Record Count” widget open in the Widget Editor, so let’s get started.

The first thing we need to define are the input to the widget, this is where the user get’s to select what table they want to query, the query itself and the title they want to display above the record count. this is done adding options to the widget. Click the hamburger menu icon in the top right of the Widget Editor and then select “Edit Option Schema”.

We need to add three options to the Widget, we’ll start with a title, Click the [+] icon in the top right of the Widget Options Schema window.

Label – Title
Name – title
– string
– The title that appears above the record count
Default Value – *Leave Blank*

Press the [+] Icon again in the top right to create our next widget option, Table selection

Label – Table to query
Name – table_to_query
– reference
Referenced Table – Table [sys_db_object]
– *Leave Blank*
Default Value – *Leave Blank*

And now for the final widget option, the query. To keep it simple, we can just accept encoded queries in here.

Label – Encoded Query String
Name – encoded_query_string
– string
– An encoded Query String, use the normal ServiceNow interface to filter the table, then right-click on the filter and select “Copy Query”
Default Value – active=true

That’s the widget options done.

We’ll start the coding with the part that should be familiar to most ServiceNow Administrators / Developers, the Server Script. As mentioned above, we will not be using the Client Script part of the Widget Editor when creating the Record Count widget, so at the top of the page, remove the checkbox from “Client Script”, this will hide the Client Script editor, leaving you with just the Server Script and the HTML Template.

Looking at the Server script box, we can see the commented instructions

This gives us a good clue about what we need to do here. We need to run a GlideRecord query and return the result of the query into the data object, but how do we get the information from the user? Well ServiceNow have made this really easy for us, along with the data object they provide an options object, which as you have probably guessed, holds the options that the user selects when setting up an instance of the widget.

The first thing we need is the name of the table. As with other reference fields on the platform, the value provided when you use them in a script is the sys_id, to get the name of the table we can perform a simple GlideRecord get query.

Now that we have the information on the table, we can move on to querying the table with the query string from the user. Now we also get to use the data object for the first time.

The last bit to do here is add a little bit of logic to ensure the Server script only runs once the widget has been setup by the user.

Now onto the HTML Template, you may want your widget to look slightly different, but in this tutorial we are going to mimic the look of the “Single Score” report in ServiceNow. We will be seeing our first interaction with AngularJS here too, don’t worry though, I’ll explain each of the AngularJS bits as we get to them.

As mentioned at the beginning of this tutorial, Bootstrap CSS classes are available in the Service Portal by default, there’s nothing you need to do to enable this. We’ll use Bootstrap CSS panels to create the canvas for our widget. If you’re not familiar with Bootstrap, you can read more about it here.

That’s our widget’s canvas setup, now we need to add some content into it. This is where we will start to see some AngularJS, in particular curly-brace expressions. Curly-brace expressions is one of the ways in which AngularJS extends HTML, anything within a double curly-brace is processed by the AngularJS framework and will be replaced by the result of the expression. This is how we are going to get the result of the Server Side script into our HTML. Let’s start with the title, this is set in the options of our widget. If you are familiar with AngularJS already, stick with me here, as there are differences between the ServiceNow Service Portal and plain AngularJS.

As you can see, we access the title in much the same way as if we were doing so in the Server Side javascript, that’s because the curly brace expression is allowing us to use javascript within our HTML, don’t let this confuse you though as you can’t run server side script inside curly-braces. The only reason we have access to the options object as that ServiceNow have set this up in the background for us.

Next we will get the result of the Server Side script.

Again the data object is only available in the curly-brace expression because ServiceNow have set this up in the background for us. Plain AngularJS would require much more from us to get the same result, so a big thank you to ServiceNow.

We now have a working widget, but we are not finished quite yet, like with the Server Side script, we are going to add some conditional logic to the HTML. We can do this again by using AngularJS, this time we will use another part of the angularJS Framework, Directives. Directives come in a few different forms, but the directive we are going to use here is fairly simple to understand. We are going to add two if statements to our HTML using HTML Attributes.

the ng-if above is our conditional statement, we have added this to the div element that is holding our widget content, this means that our widget content will show only if the ng-if statement evaluates to true. In this case that means it will only show our widget content when a table has been selected in the widget options.

One last finishing touch is to add instructions to the widget when the table hasn’t been selected.

And that is our finished widget, let’s take a peek at what it looks like in the Service Portal, it can be added by dragging the widget on the canvas of a page in the Service Portal Page Designer. Hopefully this tutorial has been of use to you, if you have any questions, please leave them in the comments section below.

One Commnet on “Creating a simple ‘Record Count’ Service Portal Widget

Leave a Reply

Your email address will not be published. Required fields are marked *