
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
One of the first things that blew me away about ServiceNow was the iTunes like way to make filters on lists, or conditions on things like UI policies. Recently, I had a need to build my own records with such filters. It turned out to be very easy and very powerful. Let me show you how you can add such flexibility to your data without adding complexity to your scripting.
Here's the story… the customer's change process required "templates" for their change tasks. They wanted to construct a library of tasks they could apply to the change request when a UI Action copied them over. At first this sounded like a quick easy reference field (change_request.u_change_model) that pointed to a Change Model Table (u_change_model). A second table "Change Model Tasks" (u_change_model_tasks) would contain the set of tasks for each model by using a Parent field to create a related list on u_change_model. Pretty straight forward. Then things got interesting.
They also wanted a series of "administrative" task models that got applied for things like pre-implementation test, pre-implementation verification, post implementation verification etc. Oh, and if there was no change model specified, use a generic model. (So much for the simple reference field.)
My solution? Use the same Change Model table and add a few additional fields. First, a true/false checkbox to determine if this was an administrative model (so I could add a reference qualifier to change_request.u_change_model to keep the Admin task models out of the list of choices. The second and third fields are the key to this whole plan. They are two fields "Table" (u_change_model.u_table) and "Conditions" (u_conditions). They are defined in the dictionary like this:
Since these types don't show up when you add new fields through (right click) Personalize> Form Layout, you'll need to add them directly from the dictionary, then place them on the form separately. Don't forget to make u_conditions dependent on u_table. It's required so the fields in the condition filter get pulled from the proper source. For my example, I forced the value of u_table to change_request (since that's the only table I'll need) and made it read-only. Be sure to place the Table field on the form or Conditions complains that it doesn't know what to do. I also chose to hide it on the form with a simple UI Policy to avoid confusion with users entering data. A second UI policy hides the conditions when Administrative is false since standard change models do not have conditions, they're selected with the reference field.
The final form looks like this:
This allows the customer to define as many standard models for implementation tasks and point to them with the Change Model field on the change form, and also include administrative tasks based on which ones match the conditions. If they want certain tasks to appear in the change tasks list based on the CI, the owner, the risk, or change type, it's all available, and more than one record can match. No need to replicate a bunch of change fields to the change_model table and write complex GlideRecord queries.
So now that we've defined the data side of things, let's look at the piece that gets the appropriate records that match the conditions…
The key is the Packages.com.glide.script.Filter and the checkRecord() method. Here's a quick little script to grab one change record and see which change model records meet the conditions of the change record data.
var cr = new GlideRecord('change_request');
cr.get('46e9b4afa9fe198101026e122b85f442'); // Specific change for this test
var mc = new GlideRecord('u_change_model');
var filter = Packages.com.glide.script.Filter;
mc.addQuery('u_active', true);
mc.addNotNullQuery('u_conditions');
mc.query();
while (mc.next()) {
var match = filter.checkRecord(cr, mc.u_conditions);
gs.print(mc.u_name + ' condition=' + mc.u_conditions + ' match=' + match);
}
That's it. My UI action "Generate Tasks" basically does this. All I changed was a few functions in the script include to copy tasks from the change_request.u_change_model field (if not empty), and trade the gs.print() for a function that copies the tasks in u_change_model_tasks (with a parent of mc.sys_id) to change_tasks.
Now you known how to use use the dictionary types "conditions" and "table_name" to create very powerful lists of records and check with ones match the given criteria without replicating lots of fields from lots of tables for specialized GlideRecord queries.
Editors note: Apologies for the long time between posts. The last couple months have been dedicated to a very aggressive timeline for a very large customer. It's been a great implementation and I look forward to sharing more cool stuff from this project in upcoming articles.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.