I look back to when I joined my first ServiceNow partner company. I asked my manager: “What kind of expertise are we missing? What holes could I fill to best benefit the company?” I’ve since added this to the bank of questions that I would ask when being interviewed. Among the answers, the most common is Service Portal.
Disclaimer: I’m simply sharing my story on how I used portal to really show value quickly. This is in no way the bible for portal developers, but rather a good guide to get started.
It makes sense. Service Portal is the part of ServiceNow that customers and end users interact with. It’s visual, interactive, and customizable. Companies want to ensure that the experience is seamless, beautiful, and most importantly, effective. As a developer or admin, portal is a great way to grow your skills in coding.
Service Portal leverages HTML, CSS, and AngularJS. You can also use jQuery on the client side, but I tend not to. The view itself is broken into a few components: HTML, CSS, Client Script, Server Script, and Link Function.
As a beginner’s guide, we’re going into the following topics — my opinionated list of things to learn to show the most value:
- HTML/CSS with Bootstrap
- AngularJS Directives / Filters
- Communicating from Client to Server
HTML/CSS with Bootstrap
This one is going to be very short. If you’re unfamiliar with Bootstrap, it’s a library of components that comes out-of-the-box with Service Portal. It allows you to quickly design widgets that are responsive. Many of the existing widgets in your instance are already built on Bootstrap (version 3.3.7).
With Bootstrap, there are tons of built-in classes. Depending on the requirement, you’ll find yourself finding everything you need through the documentation. One of the most commonly used, in my experience, is the panel class (in later versions, renamed to card).
AngularJS Directives / Filters
AngularJS directives are powerful. They’re essentially markers on DOM elements — and these flags help the compiler add the desired functionality. I’ll be going through a small subset: the ones I use regularly and remember off the top of my head. There are many more directives, and you should do your own research to find the one that fits your requirement.
ng-if
The super popular conditional directive. It evaluates an expression and if it is true, the DOM element will be rendered. In the example below, the div is shown only if isTrue is true.
<div ng-if="isTrue">This text will show</div>
ng-repeat
This directive repeats DOM elements based on an array.
<!-- HTML -->
<ul>
<li ng-repeat="person in people | orderBy: 'age'">{{person.name}}</li>
</ul>
// Client Script
api.controller = function ($scope) {
var c = this;
$scope.people = [
{ name: "Bob", age: 27 },
{ name: "Joe", age: 26 },
{ name: "John", age: 28 },
{ name: "Alex", age: 27 },
];
};
This outputs <li> tags for each item in the specified array. You access the people array and extract each item into person. As a little add-on, you can also add a filter to order the list — in this case, by ascending age.
ng-click
Similar to onclick but more powerful — you can connect this to your client script to trigger functions.
<!-- HTML -->
<button ng-click="onClick('hello')">Click Me</button>
// Client Script
api.controller = function ($scope) {
$scope.onClick = function (name) {
console.log(name);
};
};
ng-class
This directive lets you dynamically set CSS classes on an element by binding an expression. Great for conditionally applying styles based on state.
ng-model
This directive bi-directionally binds a text element to a variable.
<!-- HTML -->
<div>
<input ng-model="name" type="text" id="name" />
</div>
<div>
<div>{{name}}</div>
<button ng-click="onPress()">Press Me</button>
</div>
// Client Script
api.controller = function ($scope) {
$scope.name = "Rick";
$scope.onPress = function () {
console.log($scope.name);
};
};
Note the following:
ng-modelbinds toname, which is defined on the client scriptonPress()accesses$scope.nameand always gets the most up-to-date value- The text in the second
divalways matches what is inside theinputbox
Communicating from Client to Server
This topic is a big one. How do we communicate between the client, template, and server?
Your client side needs to be notified when an action is submitted and should send that data to your server for processing.
First, familiarize yourself with two objects: input and data.
inputis the object the client uses to communicate with the serverdatais the object the server uses to communicate with the client
Sending data from client to server
On the client side, you can call two functions to update the server: server.get() and server.update(). Since you’re calling these on the controller, you’d write c.server.get() or c.server.update().
What’s the difference? server.get() lets you pass in a custom object, whereas server.update() sends whatever the ng-models are bound to. They essentially do the same thing — use whichever fits the requirement. Both return a response you can parse for the data object.
<!-- HTML -->
<div>
<input ng-model="name" type="text" id="name" />
</div>
<div>
<div>{{name}}</div>
<button ng-click="onSubmit()">Press Me</button>
<div>{{c.data.message}}</div>
</div>
// Client Script
api.controller = function ($scope) {
var c = this;
$scope.name = "Rick";
var data = {
name: "Any data",
power: "9000",
};
$scope.onSubmit = function () {
c.server.get(data).then(function (res) {
c.data = res.data;
});
};
};
// Server Script
(function () {
data.message = "Initial Message to Client";
if (input) {
console.log(input);
data.message = "New Message from Server";
}
})();
Clicking the button triggers a call to the server, which updates data.message. The client receives the response, copies it to c.data, and the HTML template updates automatically.
This example is intentionally simple, but it gives you a solid mental model for passing data between client and server in Service Portal.
Service Portal is one of the most impactful areas you can invest in as a ServiceNow developer. Understanding how to build custom widgets opens up a huge range of possibilities — from internal tooling to polished customer-facing experiences. If you’re looking to go deeper on ServiceNow development, get in touch with the Ryspark team.