UI Action Redirect in Service Portal

I've recently come across a problem where I needed to redirect to a new URL after completing a UI Action in the Service Portal. Out-of-box, UI Actions have action.setRedirectURL(url) which will redirect in the platform view. However, this does not work for UI Actions in the Service Portal, since the Service Portal forms handle redirection in a different way than the platform. 

This blog post explains how to work around this issue by creating a custom form widget and using user preferences to save a redirection URL.

Step 1: Build a custom form widget

To avoid having to clone or customize the out-of-box Form widget-form widget, begin by creating a new widget that will embed it instead.

Server Script

// Set this per your requirements
data.options = {
	view: 'sp'
};

data.widget = $sp.getWidget('widget-form', data.options);

HTML Template

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

Step 2: Configure the UI Action

This example will use the “Insert and Stay” UI Action, but any action in which you would be using action.setRedirectURL(url) will work.

The idea behind this is that we will be setting a user preference with the URL that we want the user to be redirected to in the Service Portal after completing the UI Action.

The name of this user preference will be based on the table name that the UI Action is on, so that our custom form widget from Step 1 knows which user preference to grab. This code sample will use the Incident [incident] table.

Insert and Stay Script

doInsertAndStay();
function doInsertAndStay() {
    var saveMe = current;
    if (typeof current.number != 'undefined' && current.number)
        current.number = ""; // generate a new number
    else if (typeof current.u_number != 'undefined' && current.u_number)
        current.u_number = ""; // generate a new number
    
    // Modify this line to save the sys_id of the newly inserted record
    var id = current.insert();
    
    action.setRedirectURL(saveMe);

	// Since action.setRedirectURL doesn't work in the Service Portal, need to save the URL to redirect to within the custom form widget
	// General format: gs.getUser().savePreference(<name>, <url>);
	gs.getUser().savePreference('incident.redirectURL', '/sp?id=page_id_here&table=incident&sys_id=' + id);
}

Step 3: Finalize the custom form widget

Now that our UI Action is configured, we need to grab that user preference in our widget and then update the URL to that value.

Server Script

// If a UI Action for this table has set a user preference, then after using the action this will contain the URL to redirect to
data.redirectURL = gs.getUser().getPreference(data.widget.data.table + '.redirectURL');

Client Script

c.redirect = function(url) {
	$location.url(url);
};

Link Function

scope.$on('spModel.uiActionComplete', function(event, response) {
	scope.c.server.update().then(function(response) {
		if (response.redirectURL) controller.redirect(response.redirectURL);
	});
});

Step 4: Try it out

With everything set up, now we can navigate to the page in our Service Portal that has an instance of our custom form widget.

Make an update to the record values, and hit the “Insert and Stay” UI Action. If everything is set up properly then we should be redirected to the new URL, in this case the newly inserted Incident record!

As another check, view the User Preferences table to make sure that there is a new preference named incident.redirectURL that would have been created from the UI Action.


While this example showed how you can redirect to the same page id but with a different sys_id of a record, this idea can be applied to completely different URLs and UI Actions beyond “Insert and Stay” as well. 

Something to consider is whatever naming preference you decide on for the user preferences (incident.redirectURL vs. incident.URL), it must be applied throughout any additional UI Actions that need to leverage the functionality from this custom form widget.

As a reference, here is the final Widget and UI Action code:

Widget

HTML Template

<!-- HTML Template -->
<div>
  <sp-widget widget="data.widget"></sp-widget>
</div>

Client Script

// Client Script
api.controller = function($scope, $location) {
	var c = this;

	c.redirect = function(url) {
		$location.url(url);
	};
};

Server Script

// Server Script
(function() {
	// set this per your requirements
	data.options = {
		view: 'sp'
	};

	data.widget = $sp.getWidget('widget-form', data.options);

	// if a UI Action for this table has set a user preference, then after using the action this will contain the URL to redirect to
	data.redirectURL = gs.getUser().getPreference(data.widget.data.table + '.redirectURL');
})();

Link Function

// Link Function
function link(scope, element, attrs, controller) {
	
  scope.$on('spModel.uiActionComplete', function(event, response) {
		scope.c.server.update().then(function(response) {
			if (response.redirectURL) controller.redirect(response.redirectURL);
		});
	});
}

UI Action

doInsertAndStay();

function doInsertAndStay() {
    var saveMe = current;
    if (typeof current.number != 'undefined' && current.number)
        current.number = ""; // generate a new number
    else if (typeof current.u_number != 'undefined' && current.u_number)
        current.u_number = ""; // generate a new number

    // Modify this line to save the sys_id of the newly inserted record
    var id = current.insert();

    action.setRedirectURL(saveMe);

    // since action.setRedirectURL doesn't work in the Service Portal, need to save the URL to redirect to within the custom form widget
    // General format: gs.getUser().savePreference('<name>', <url>);
    gs.getUser().savePreference('incident.redirectURL', '/sp?id=redirect_demo&table=incident&sys_id=' + id);
}

Hopefully this method will help with redirecting in the Service Portal after completing a UI Action. Feel free to reach out to me @Jesalyn on the SNDevs Community for further discussion of this topic!

Jesalyn Smith

Jesalyn is a ServiceNow Developer who focuses on designing and developing creative, usable experiences across the platform. She currently focuses on Service Portal with an increasing interest in Next Experience and is excited to take on new development challenges and inspire new appreciation for CSS.

https://jesalyn.dev
Previous
Previous

How I Learned about Business Rules and Client Scripts

Next
Next

On ServiceNow and Hacktoberfest '22