The introduction of the Service Portal, using AngularJS and Bootstrap, has given ServiceNow considerable flexibility, allowing customers to develop portals to suit their own specific needs.

While attribution depends on whether you subscribe to Voltaire, Winston Churchill, or Uncle Ben from Spiderman, “With great power comes great responsibility.” And this is especially true when it comes to the Service Portal. Customers should tread lightly so as to use the flexibility of the portal correctly.

A good example of this arose during a recent customer engagement, where the requirement arose to allow some self-service portal users the ability to see all the incidents within their company. This particular customer provides services across a range of other smaller companies, and wanted key personnel in those companies to see all their incidents (without being able to see those belonging to other companies, and without being able to update or change others’ incidents). 

The temptation was to build a custom widget from scratch using AngularJS, but simplicity won the day. Instead of coding, testing, and debugging a custom widget, JDS reused an existing widget, wrapping it with a simple security check, and reduced the amount of code required to implement this requirement down to one line of HTML and two lines of server-side code.

The JDS approach was to instantiate a simple list widget on-the-fly, but only if the customer’s security requirements were met.

Normally, portal pages are designed using Service Portal’s drag-and-drop page designer, visible when you navigate to portal configuration. In this case, we’re embedding a widget within a widget.

We’ll create a new widget called secure-list that dynamically adds the simple-list-widget only if needed when a user visits the page.

Let’s look at the code—all three lines of it:

HTML

<div><sp-widget widget="data.listWidget"></sp-widget></div>

By dynamically creating a widget only if it meets certain requirements, we can control when this particular list widget is built.

Server-Side Code

(function() {
                if(gs.getUser().isMemberOf('View all incidents')){
                                data.listWidget = $sp.getWidget('widget-simple-list', {table:'incident',display_field:'number',secondary_fields:'short_description,category,priority',glyph:'user',filter:'active=true^opened_by.company=javascript:gs.getUser().getCompanyID()',sp_page:'ticket',color:'primary',size:'medium'});
                }             
})();

This code will only execute if the current user is a member of the group View all incidents, but the magic occurs in the $sp.getWidget, as this is where ServiceNow builds a widget on-the-fly. The challenge is really, ‘where can we find all these options?’

How do you know what options are needed for any particular widget, given those available change from one widget to another? The answer is surprisingly simple, and can be applied to any widget.

When viewing the service portal, administrators can use ctrl-right-click to examine any widgets on the page. In this case, we’ll examine the way the simple list widget is used by selecting instance options.

Immediately, we can see there are a lot of useful values that could be set, but how do we know which are critical, and what additional options there are?

How do we know what we should reference in our code?

Is “Maximum entries” called max, or max_entry, or max_entries? Also, are there any other configuration options that might be useful to us?

By looking at the design of the widget itself in the ServiceNow platform (by navigating to portal-> widgets), we can scroll down and see both the mandatory and optional configuration values that can be set per widget, along with the correct names to use within our script.

Looking at the actual widget we want to build on-the-fly, we can see both required fields and a bunch of optional schema fields. All we need to do to make our widget work is supply these as they relate to our requirements. Simple.

{table:'incident',display_field:'number',secondary_fields:'short_description,category,priority',glyph:'user',filter:'active=true^opened_by.company=javascript:gs.getUser().getCompanyID()',sp_page:'ticket',color:'primary',size:'medium'}

Also, notice the filter in our widget settings, as that limits results shown according to the user’s company…

opened_by.company=javascript:gs.getUser().getCompanyID()

This could be replaced with a dynamic filter to allow even more flexibility, should requirements change over time, allowing the filter to be modified without changing any code.

The moral of the story is keep things simple and…

Don't reinvent the wheel

Our team on the case

Document as you go.

Peter Cawdron

Consultant

Length of Time at JDS

5 years

Skills

ServiceNow, Loadrunner, HP BSM, Splunk.

Workplace Passion

I enjoy working with the new AngularJS portal in ServiceNow.

Leave a Reply