Customisation of the Service Portal’s date and time picker

The date and time picker widget on the Service Portal is well built in the London release of ServiceNow. It automatically formats the date based on the users’ settings. Moreover, it shows the names of the day and month according to the users’ language and can support 12-hour standard and 24-hour military clock formats, out of the box, without any further configuration.

However, it may happen that a customer requires additional customisation of the widget, which is unfortunately not supported by ServiceNow at the moment. For instance, display the date and time picker next to each other, increase minute stepping, or change the first day of the week. This blog post can help to achieve such customisations.

Note

The following guide is a custom-developed solution. For example, it is not a standard ServiceNow customisation. So, if an instance is changed based on the following steps, the related templates will need to be updated and configured after a ServiceNow version change. The best way to do so is to redo these steps following a successful upgrade.

Preparation

I will use an untouched London version developer instance for this blog post. I used the latest version of Chrome for this example, but the required steps should be reproducible in Firefox or Microsoft Edge as well.

First step: Clone a field template

In order to customise the widget, first you have to clone and overwrite an out-of-the-box Angular template: sp_form_field.xml.

You can find the template’s source with your browser’s developer tools or by checking Service Portal’s HTML source in the browser.

Open the developer tools by pressing “F12” on your keyboard, then select the “Elements” tab, and look for a script element with the ID “sp_form_field.xml”. Subsequently, copy its content to the clipboard.

Having done so, you should create a new “Angular ng-template” record in ServiceNow. Set its ID to “sp_form_field.xml” and its template to the copied and formatted source of the original one.

In the related “Widget” field, you should select “Header menu” or some other widget included in all pages of your portal.

Why “Header menu”?

I recommend using Header menu or any other global widget in your Service Portal in order to overwrite as the starting point, because portal pages can contain other forms in addition to catalogue item forms. Moreover, in order to overwrite all date pickers through the portal, it is necessary to include the customised template in every page. The easiest way to do so is to assign the template to a widget included in all pages, such as the header widget typically.

After this, you should find the line with the following content:

<sp-date-picker sn-change="fieldValue(newValue, displayValue)" 
ng-switch-when="glide_date_time" 
field="field" 
sn-disabled="field.isReadonly()" 
ng-model="field.stagedValue" 
ng-model-options="{getterSetter: true}" 
sn-include-time="true" ng-if="c.depsLoaded">
</sp-date-picker> 

Subsequently, replace it with the following:

<sp-custom-date-picker   sn-change="fieldValue(newValue, displayValue)" 
         ng-switch-when="glide_date_time"
         field="field"
         sn-disabled="field.isReadonly()"
         ng-model="field.stagedValue"
         ng-model-options="{getterSetter:   true}"
         sn-include-time="true"
         ng-if="c.depsLoaded">
</sp-custom-date-picker>

At the end, you should have a record as follows:

So, instead of the out-of-the-box “sp-date-picker” directive, we will use the custom “sp-custom-date-picker”. But, what is this exactly? I will explain it in the following chapter.

Second step: Clone the date picker directive

sp-date-picker” is an AngularJS directive created by ServiceNow. Its goal is to wrap and initialise the date picker element and bind its value to the form field as well.

To read more about AngularJS directives provided in the official documentation, click on the following link: https://docs.angularjs.org/guide/directive

This directive is not meant to be customised. Therefore, you will not find it in the “Widget Angular Providers” table. Instead, we have to procure its code in a way that is similar to the process by which we got the template.

Navigate to the service portal again. Open your developer tools by pressing “F12” on your keyboard and select the tab “Sources”. Subsequently, press “Shift+Ctrl+F” to search within source codes, and search for “spDatePicker”. Once you have found it, copy its source, which begins with the word “function”, to the clipboard.

Now, you should create a new “Widget Angular Provider” record in ServiceNow. Set its name to “spCustomDatePicker” and its client script to the copied and formatted source of the original one.

At the end, you should have a record like the following:

Before we can finally proceed to the customisation of the picker, only one is step left. You have to assign the newly created provider as an Angular Provider in the same widget that you set up as “Widget” for the clone of the template; check “Header menu” in my example.

In order to do so, open your selected widget and add “spCustomDatePicker” as a provider:

At this point, if you open a catalogue item form, which has a “date/time” type variable, you should be able to see the same as before the customisation. But actually, the rendered date picker is already our newly created directive. Let’s change its configuration in the next step!

Third step: Customisation

Open your newly created Angular directive record in ServiceNow, and locate the following part in its source:

var dp = element.find('.input-group-btn').datetimepicker({ … })

Here, you can change the actual configuration of the date picker element.

Date and time picker next to each other

Configuration

var dp =   element.find('.input-group-btn').datetimepicker({
       keepInvalid: true,
       pickTime: scope.snIncludeTime === true,
       format: scope.format,
       locale: g_lang,
     sideBySide:   true,
language: g_lang
   }).on('dp.change', onDpChange); 

Result

Display week numbers

Configuration

var dp = element.find('.input-group-btn').datetimepicker({
           keepInvalid: true,
           pickTime: scope.snIncludeTime   === true,
           format: scope.format,
           locale: g_lang,
           sideBySide: true,
           calendarWeeks: true,
           language: g_lang
       }).on('dp.change',   onDpChange);   

Result

More configuration options

For the full list of available configuration options, you can check the official documentation of the date picker widget by clicking the following link: http://eonasdan.github.io/bootstrap-datetimepicker/Options/

Please note: ServiceNow uses the 3.x version of the widget, whilst the available documentation is for the 4.x version. Thus, some options might not be configurable in ServiceNow yet!

Disable direct user input

If you would like to restrict portal users from typing in arbitrary date time strings, you can also make the date field “read only”. However, it would still be editable through the picker.

Open your newly created Angular directive record in ServiceNow, and properly locate the following part within its “template”:

ng-readonly="snDisabled"

Then, replace it with the following:

ng-readonly="true"

As a result, the input field becomes read only, but users can still select valid date and time values:

Change the first day of the week

It is a common request to set Monday as the first day of the week instead of the default, i. e. Sunday.

This step can be performed without customising the entire date picker widget. All you have to do is to create a new “UI script” record with the following content:

moment.updateLocale('en', {
     week: {
       dow: 1,
     },
   });

Then, add the script to your service portal’s “JS Includes” list:

Result

Explanation: The date picker widget (http://eonasdan.github.io/bootstrap-datetimepicker/) in ServiceNow uses Moment.js (https://momentjs.com/docs/#/get-set/weekday/) to determine the first day of the week, based on the users’ current language. In Moment.js, the “en” locale has “0” set as the first day of week by default, which means Sunday, but with the aforementioned script, we can override this to “1”, which means Monday in this case.

To see all Moment.js locale configurations, click on the following link:

https://github.com/moment/moment/tree/develop/locale

About the Author

Matyas Peto is a Lead ServiceNow Service Portal developer, who has successfully completed numerous ServiceNow Service Portal projects with unique features and custom Service Portal elements for enterprise customers in the EU and USA.

Updates

Blog