ServiceNow adds a ton of great functionality to each new product release. Often times, the most helpful and useful features (at least to a long-time user of the system) are enhancements to simplify or improve on existing functionality. Unfortunately, these are often some of the most under-appreciated and end up getting lost in the marketing hype of all of the brand new capabilities that you may or may not use. One such example that recently arrived to ServiceNow is ‘Dynamic filters’. In this post, I’ll share what dynamic filters are, and show how you can extend and leverage this capability to improve your own ServiceNow system.
The ServiceNow wiki does a decent job of explaining the basic concept and usage of dynamic filters. There are 1000’s of scenarios where users of the system need to query for information, display a list of data, generate a report, or values from a reference field based on a specific, logical filter criteria. There are many examples of this…my Group’s work, my approvals, records assigned to other members of my groups, etc. These types of scenarios, though simple on the surface, actually require sometimes very complex code to query for and return the correct data. ServiceNow has always allowed you to do this, of course, but the approach (asking a typical end-user to remember and correctly populate a specific query string with a function call directly in the filter) really isn’t one that works well — even if that user happens to be an admin of the system. Those query strings generally look something like this and can be pasted directly into any filter criteria to return information…
javascript:getRoledUsers();
etc...
The general idea behind dynamic filters is to allow a ServiceNow administrator to pre-define the filter query logic to return the correct information from a back-end function, then set up a dynamic filter definition to point to that information via a simple label invoked from any filter field criteria in the system. These dynamic filters can be as flexible and complex as you need them to be, but the end-user doesn’t need to know or understand any of that complexity in order to benefit from them!
There are several of these dynamic filters defined out-of-box that you can use right away as examples for creating your own. You can find them under ‘System Definition -> Dynamic Filter Options’ in your left nav. For more complex scenarios, you’ll actually point your dynamic filter to a back-end Script Include function that contains all of the logic and does the heavy lifting.
One common filter criteria that I hear about all of the time that isn’t handled out-of-box is to filter for records associated to members of my groups via some user field (usually an assignment or ownership of some sort). Tickets assigned to members of my groups, outstanding approvals for members of my groups, etc. This configuration can be added to your system by following a few simple steps as shown below…
- Create a new ‘On Demand’ Script Include function.
- Create a new ‘Dynamic Filter’ record
The on-demand function is great and allows you to easily return the data you want. From any place you can call scripts in the system. This is fantastic for business rules, workflow scripts, etc. but the average user running a report or filtering a list is not going to know (nor should they need to know) the exact syntax and function name to call. This is where Dynamic Filters come in! We can wrap that script call in a friendly label that displays in any filter anywhere in the system so that a normal human being can access it as well. Your dynamic filter for the script above should look just like I’ve shown in the screenshot below. You can create it by navigating to ‘System Definition -> Dynamic Filter Options’
I’ve written about this capability before so you can reference that article for more details if you need. Creating this script include will allow us to easily call a reusable function to return the data we want…in this case a list of users that belong to the same group as the current user. The basic idea for this function is to get a user’s groups, then find the active group members sys_id values associated with those groups and add them to an array to be returned. You can navigate to ‘System Definition -> Script Includes’ in your left nav to create this. Don’t forget that the ‘Name’ value of any on demand script include (like this one) needs to exactly match the name of the function you’re calling in the script!
Name: getMyGroupMembers
Active: True
Client callable: True
Description: Queries for members of groups that the currently logged-in user is also a member of.
Script:
var myGroups = gs.getUser().getMyGroups();
var groupsArray = new Array();
var it = myGroups.iterator();
var i=0;
var groupMemberArray = new Array();
while(it.hasNext()){
var myGroup = it.next();
//Query for group members
var grMem = new GlideRecord('sys_user_grmember');
grMem.addQuery('group', myGroup);
//Only return active users
grMem.addQuery('user.active', true);
grMem.query();
while(grMem.next()){
//Add to user sys_id to array
groupMemberArray.push(grMem.user.toString());
}
i++;
}
return groupMemberArray;
}
NOTE: One interesting bit of information I discovered while working with dynamic filters is the way that the system handles the encoded query strings for them. You end up with a query string (that you could reuse) that looks like this…
assigned_toDYNAMIC1a570fd90856c200aa4521695cf1eb24
The ‘DYNAMIC’ keyword indicates the use of a dynamic filter, and what follows is the sys_id of the corresponding dynamic filter record.
The end result is a nice, dynamic filter option for filtering where the user listed in a user field is a member of one of your groups! This is just one example of a fantastic capability in ServiceNow. There are lots of other use cases that you can add using this same approach.
Awesome Mark,it really solves so much of issues related to reference qualifier.
Thank you Mark..nice article
You’re welcome!
Nice work Mark.
Just a quick question how would you exclude a group from this as we have groups to separate what people can see on our Self Service Portal. eg Catalogue – NZ means they can see NZ items.
You can do that in a couple of ways, but the simplest based on how I’ve constructed the script above is to add additional query lines to the script include. Right under the ‘user.active’ line you could add lines like this…
grMem.addQuery(‘group.name’ ‘!=’ ‘NAMEOFYOURGROUPTOEXCLUDE’);
Works a treat thanks
Nice stuff! Has anyone tried to create a dynamic filter for a date/time field?
I thought I had a good script I hooked into a new dynamic filter for field type Date/Time on table global with the “Available for filter” box checked but no dynamic ones appear in the list. No errors warnings in logs. Any ideas?
Hi Ruth
I’ve just been trying to do exactly the same with the same results…did you have any joy in making this work for date/time fields?
Thanks – Andy
Thanks for the great article and tips. I always find this site useful. One thing I just realised and noted from the official ServiceNow wiki is that the name of the function must that same name as the script include. This was not initially clear to me and I wondered why my client-callable script include, that contained several functions was not working. The reference to the wiki is here: http://wiki.servicenow.com/index.php?title=Using_Filters_and_Breadcrumbs#Scripted_Filters, refer to point 2 ”
Thanks
–Tony
Thanks Tony, I’ve clarified the article now. 🙂