ServiceNow is a very powerful and very flexible IT management platform. Because it is so easily customized, it can be easy to design yourself into a corner if you don’t plan appropriately. UI Actions are a frequently customized component of ServiceNow, and are the cause of many of the design-related issues I’ve encountered.
UI Actions allow custom code to be run at the click of a link or button within the ServiceNow interface. They can be set to run within the browser, on the server, or both (a neat hack by Mark Stanger of ServiceNowGuru.com). It is possible to implement features via UI Actions that will result in headaches down the road. To illustrate this risk, consider the following scenario:
You want to make it easy for individuals to close an Incident, so you create a UI Action named “Close Incident” on the Incident form. The code for your UI Action will run on the server, and it looks something like this:
current.incident_state = 7; // Closed current.active = false; current.update();
In addition to your UI Action, you have ACLs defined to prevent updates to closed Incidents. Everything appears to work well. Users are happy and your process is maintained correctly.
Now, fast forward a few months. Your users have grown accustomed to using the “Close Incident” button. Most Incidents have the necessary details filled in, but not all of them. Your audit team hands down a new requirement that every closed Incident have the Configuration Item (CI) field filled in.
Here’s where things get sticky. You could use a UI Policy to make the CI field mandatory, but UI Policies depend on the browser to function correctly. They don’t work on mobile views, nor do they protect against updates via web services or other scripts. You could use a Data Policy, which solves many of the issues of the UI Policy, but at what point would you make the field mandatory? If you make the field mandatory only on closed Incidents, the built-in UI Policy behavior won’t indicate the field is mandatory until the incident is actually closed. This will result in frequent “Invalid Update” rejections and frustrate your users. You could extend the UI Action code to check for this field and abort if it’s not filled in, or implement a “before” Business Rule to do the same, but now you’re duplicating the functionality of UI Policies and Data Policies. It turns into a big mess.
There’s a better way…
Avoid making changes to the current record from within a server-side UI Action script when possible. Instead, try to perform all data modification within the browser or in client-side code. This allows you to take full advantage of UI Policy (or Data Policy) logic. Consider our example above, but instead move the logic to a client-side script and forgo the update() call:
g_form.setValue('incident_state', '7'); // Closed
This will change the Incident State field to “Closed”, but will not submit the form. The Data Policy which requires the CI field on closed Incidents will mark the CI field mandatory, and the user will be required to fill it in before saving the record. No extra input checking or validation code is required.
There will be times when you’ll find it necessary to make changes to the current record from within a “before” Business Rule or UI Action, and that’s OK. Just make sure you understand the impact it will have on your UI and Data Policy functionality.
Leave a Reply