The problem: I want to add styling to my dashboards, but ServiceNow doesn’t have a way to add custom CSS to dashboards
The solution: use a system UI Widget plus a UI Page to add css to your dashboards. Psst…there’s a video — way down there!
This solution is using DOM manipulation. In nearly every bit of ServiceNow documentation doing this is frowned upon. So you need to do a bit of risk analysis on this. Here’s my risk analysis:
RISK ANALYSIS:
- This is standard front-end development using normal css.
- This is standard jQuery front-end development using normal jQuery methods.
- The chances of ServiceNow changing the css classes used in dashboards exists, but the likelihood is low (my assumption).
- If it breaks – simply back out of this solution by removing the UI Widget from any dashboard where it’s used.
BENEFITS: You get to do some pretty darn nifty styling of your dashboards.
How does this work?
- Dashboards use css classes in elements to manage the look and feel of the dashboard. Any reports inserted in dashboards also use css classes to manage look and feel. In a UI Page’s HTML section we can add a <style>…</style> section to contain css that finds specific parts of dashboard elements and any inserted report elements.
- To get a UI Page into a dashboard, we must create a System UI widget that references a UI Page.
- Getting the UI Widget into the dashboard is the same process as adding reports. Click the plus (+) sign when viewing a dashboard as an admin user. That exposes what can be inserted. Click on the “Widget Category” dropdown at the top and you should see the widget you created. Click on the widget and insert it into the dashboard.
IMPORTANT BITS:
- This widget:
- Must be on the top of any other inserted items,
- Needs to occupy the full width of the screen, and
- Must have as small a height as possible – so drag the bottom of the widget up until you can’t drag it anymore.
- NOTE: the css we include in the UI Page will do the magic of hiding this entire widget while the dashboard is being viewed, and will unhide it when you click the (+) to manage dashboard items.
STEPS:
- Create a System UI Widget.
- Create a UI Page.
- Create or edit a dashboard and add some reports.
- Edit the dashboard by inserting the widget.
- Shrink the widget’s height to be as small as possible – drag the bottom of the widget up until you can’t drag any more.
- Exit dashboard editing mode.
- Refresh the browser to refresh the dashboard.
- Notice how the styling widget and all inserted items slide up so the styling widget becomes hidden.
- Click the (+) to edit and notice the styling widget reappears.
CODE SAMPLES: Copy these code snippets into the applicable sections in the UI Widget and UI Page
UI Widget:
Script section:
// https://docs.servicenow.com/en-US/bundle/tokyo-platform-user-interface/page/use/dashboards/task/create_widget_displays_webpage.html
// source: https://www.sn-101.com/i-just-want-some-style-in-my-dashboards/
function sections() {
return {
'Dashboard Styler (hidden during normal operations)': {
'type': 'sdb_dashboard_styler' // type is the value in the Name field of the UI Page
}
};
}
// nothing below here needs to be changed //
function render() {
var scope = gs.getCurrentScopeName();
scope = (scope == "rhino.global" ? "" : scope + "_");
var page = renderer.getPreference('type');
return renderer.getRenderedPage(scope + page);
}
function getEditLink() {
var scope = gs.getCurrentScopeName();
scope = (scope == "rhino.global" ? "" : scope + "_");
var page = renderer.getPreference('type');
return "sys_ui_page.do?sysparm_query=name=" + scope + page;
}
UI Page:
HTML:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- a little css styling please -->
<style type='text/css'>
.list-title, .highcharts-title {
font-size: 18px !important;
font-weight: bold !important;
}
.embeddedReport{
background-color: #fff;
margin: 0px 5px 35px 0px;
padding: 20px;
border: 1px solid #474747;
border: 1px solid #095a91;
box-shadow: 0px 0px 12px #5C5C5C;
border-radius: 6px;
}
.grid-widget-header{
font-weight: bold !important;
font-size:16px !important;
color: #000 !important;
background-color: #C1C1C1 !important;
background-color: #2d95de !important;
}
.title-content{
font-weight: bold !important;
}
.grid-widget-content, .grid-stack-item-content{
background-color: #fff !important;
}
.grid-stack-container, .grid-widget-content, .grid-stack-item{
background-color: #D3D3D3 !important;
background-color: #fff !important;
}
.grid-stack-item-content{
box-shadow: 0px 0px 6px #5C5C5C;
box-shadow: 0px 0px 8px #bfbfbf;
}
.grid-stack-item-border{
border: 3px solid #000 !important;
border: 2px solid #095a91 !important;
border-radius: 6px;
}
.hideStyler{
top: -110px !important;
margin-bottom: 105px !important;
margin-bottom: 115px !important;
}
#stylerHelperInfo{
font-size: 12px;
font-style: italic;
}
.introInfo{
font-size: 28px;
font-weight: bold;
font-style: italic;
}
</style>
<!-- Because this HTML for the styler ui page appears briefly before it's hidden, let's put some useful information in here in case users see it - it acts like any other 'loading...' distraction -->
<div id="stylerHelperInfo">
This is a UI Page inserted with a System UI Widget. It is designed to provide a way to create css styling for dashboards and inserted reports. It's hidden by css when the page loads and is unhidden when an admin clicks the (+) to add widgets.
</div>
<div id="loadingReports" class="introInfo">
... LOADING REPORTS
</div>
<!--
-->
</j:jelly>
Client Script:
/*
What's going here folks? Glad you asked.
First - when the dashboard loads, the inserted widget that calls this UI page must be at the top of the dashboard
to allow the css to be implemented - why? It appears that widgets are loaded on demand - so if the styler widget
is at the bottom, it doesn't appear until the user scrolls to where it becomes visible and then the css doesn't take effect
Second - so we really don't want that ugly widget at the top - let's hide it when the page loads with some jQuery to
add a class to the .grid-stack-item-content class - if you use your browser dev tools you can investigate the classes
ServiceNow uses for all the parts of dashboards.
Finally, once the styler widget is hidden, it stays hidden - meaning you cannot delete it if you want to. So,
we wait for the (+) button (button[ng-if='canEditSelectedDashboard']) to be clicked and if we've already clicked the (+)
we show the styler widget, otherwise we hide it when we click the (+) againt to stop adding widgets to the dashboard.
source: https://www.sn-101.com/i-just-want-some-style-in-my-dashboards/
*/
jQuery(".grid-stack-item-content").addClass('hideStyler');
jQuery("button[ng-if='canEditSelectedDashboard']").click(function(){
var buttonState = jQuery(this).attr('aria-pressed');
switch(buttonState){
case "true":
// if true means the button was previously clicked and now we're hiding the slide-out panel
jQuery(".grid-stack-item-content").addClass('hideStyler');
break;
case "false":
// if false means the slide-out panel is now being exposed
jQuery(".grid-stack-item-content").removeClass('hideStyler');
break;
}
});
VIDEO:
Here’s a video showing how I used the UI Page, UI Widget and typical dashboard to add CSS styling to a ServiceNow dashboard;