Building a Custom Slider Widget on a ServiceNow Portal Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 hours ago
Interactive and visually appealing content can significantly enhance the user experience on ServiceNow portals. One effective way to showcase multiple offerings or features is by using a custom slider widget. In this guide, we’ll walk through creating a responsive slider widget using SwiperJS that highlights key portal services such as upcoming events, travel status, and document uploads.
Widget Preview
Here’s how the Custom Slider Widget looks on the ServiceNow portal:
Desktop view with interactive cards:
Desktop view with "View Details" button on hovering on the first card icon:
Widget Overview
The Custom Slider Widget allows portal users to:
Navigate through multiple cards featuring different services.
View short descriptions and offerings at a glance.
Access detailed pages with a single click.
Experience a responsive and mobile-friendly layout.
Here’s what a typical slider card contains:
Image/Icon representing the service.
Heading and short description for quick context.
List of offerings/features.
Action button linking to a detailed page.
Step 1: Widget HTML
We use SwiperJS for the slider functionality and Font Awesome for icons.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide" ng-repeat="slide in c.data.slides">
<div class="card">
<div class="card-header">
<img src="{{slide.icon}}" style="height:150px;border-top-left-radius:1rem;border-top-right-radius:1rem;width:100%;"/>
</div>
<div class="card-body">
<div class="card-top">
<h1>{{slide.heading}}</h1>
<p>{{slide.shortDesc}}</p>
</div>
<ul class="card-offerings">
<li ng-repeat="item in slide.offerings">
<i class="fa fa-check text-success" style="color:#61de4b;"></i> {{item}}
</li>
</ul>
</div>
<div class="card-footer">
<a class="btn expanding-btn" href="?id={{slide.page}}">
<span class="label">View Details</span>
<i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
</div>
</div>
<!-- Arrows -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<!-- Pagination -->
<div class="swiper-pagination"></div>
</div>
Step 2: Widget CSS
The CSS ensures a modern card layout, responsive slider, and smooth hover animations.
.swiper {
width: 80%;
margin: auto;
padding-bottom: 50px;
margin-top: 50px;
}
.swiper-slide {
display: flex;
justify-content: center;
align-items: stretch;
}
.card {
background: #fff;
border-radius: 1rem;
padding: 1rem;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
max-width: 350px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-header img {
height: 150px;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
width: 100%;
}
.card-body {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 1rem 0;
}
.card-offerings {
list-style: none;
padding: 0;
margin: 0;
}
.card-offerings li {
margin: 0.4rem 0;
}
.expanding-btn {
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: 50%;
background-color: #006f62;
color: white;
border: none;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.expanding-btn:hover {
width: 100%;
border-radius: 50px;
background-color: white;
border: 2px solid #006f62;
}
.expanding-btn:hover .label {
opacity: 1;
color: green;
}
Note: The full CSS includes Swiper arrows styling and card typography, making the slider visually appealing and functional across devices.
Step 3: Client Script (Controller)
We dynamically load SwiperJS and initialize the slider with responsive breakpoints.
api.controller = function($timeout, $scope) {
var c = this;
$timeout(function() {
var script = document.createElement('script');
script.src='https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js';
script.onload = function() {
new Swiper(".mySwiper", {
slidesPerView: 3,
spaceBetween: 30,
pagination: { el: ".swiper-pagination", clickable: true },
navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev" },
breakpoints: { 0: { slidesPerView: 1 }, 768: { slidesPerView: 2 }, 1024: { slidesPerView: 3 } }
});
};
document.head.appendChild(script);
}, 0);
};
Step 4: Server Script (Data Setup)
We define the content for each card, including icons, headings, descriptions, offerings, and target pages.
(function() {
data.slides = [
{
label: 'Upcoming Events',
icon: 'dashboard-stock-img.png',
heading: 'Upcoming Events',
shortDesc: 'Easily track and manage all your scheduled journeys in one place.',
offerings: ['View all scheduled trips', 'Quick access to travel details', 'Stay prepared with reminders'],
page: 'upcoming-event'
}, {
label: 'Active Travel Case Status',
icon: 'case-status.png',
heading: 'Active Travel Case Status',
shortDesc: 'Track the progress of your travel cases.',
offerings: ['Monitor active travel requests', 'Real-time case updates', 'Faster issue resolution'],
page: 'travel_status'
}, {
label: 'Upload Documents',
icon: 'upload-document.png',
heading: 'Upload Documents (Passport, Visa, etc.)',
shortDesc: 'Store and manage travel documents securely.',
offerings: ['Upload passport and visa copies', 'Centralized document storage', 'Quick access during travel'],
page: 'upload_documents'
}, {
label: 'Report an Issue',
icon: 'report-issue-stock.png',
heading: 'Report an Issue (Support Case)',
shortDesc: 'Get assistance when you need it.',
offerings: ['Log travel-related issues easily', 'Track support case status', 'Receive timely help'],
page: 'report_now'
}
];
})();
Note:
Instead of providing data directly in the server script, it is considered best practice to use instance options or retrieve data from a System Property, as this makes the code more reusable.
Steps to Add an Image in ServiceNow Portal Widget
1. Using Images from All > System UI > Images Table (db_image)
If the image is already stored in All > System UI > Images table:
You can directly specify the image name in the src attribute of the <img> tag.
Example:
<img src="image-name" />
2. Using Images from a Table Field (Image-Type Field)
If the image is stored in a table field (e.g., an avatar field in the User table), follow these steps:
Step 1: Get the sys_id of the image field.
Glide the record and get the field value (which is the sys_id of the image).
Step 2: Use the sys_id in the src attribute as follows:
<img src="/sys_attachment.do?sys_id=sys_id_of_image" />
Step 3: To display the image dynamically, store the src value in your server script (e.g., as part of your JSON data):
/* Server script */
data.photo = "/sys_attachment.do?sys_id=sys_id_of_image";
Step 4: Bind the image in the HTML using Angular syntax:
<img src="{{data.photo}}" />
Step 5: Navigating to Widgets in ServiceNow
To create this slider in your ServiceNow instance:
Go to All > Service Portals > Widgets (sp_widget table).
Click New to create a custom widget.
Copy the HTML, CSS, Client Script (Controller), and Server Script into the respective sections.
Save and add it to your desired portal page.
Features & Benefits
Responsive Design: Works seamlessly on mobile, tablet, and desktop.
Interactive Cards: Hover effects and expanding buttons enhance engagement.
Dynamic Content: Easy to update slides via server script.
Reusable Widget: Can be used across multiple portals or pages.
Conclusion
The Custom Slider Widget is an effective way to highlight multiple services and resources on your ServiceNow portal. By leveraging SwiperJS and dynamic data binding, you can create a visually appealing and interactive user experience that keeps portal visitors engaged.
- 74 Views