dot-walking request table to requested item for ui action button
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
You can't access RITM field when UI action is on REQ table
1 Request can have multiple RITMs?
how will you handle this then?
If you are sure always 1 REQ will have 1 RITM then you can use script include and call that from UI action condition
new RequestUtils().canCancelRequest(current)
var RequestUtils = Class.create();
RequestUtils.prototype = {
initialize: function() {},
canCancelRequest: function(current) {
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request', current.sys_id);
ritm.addQuery('car_item.name', 'Your Item Name Here');
ritm.query();
return ritm.hasNext();
},
type: 'RequestUtils'
};
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hope you are doing good.
Did my reply answer your question?
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
ServiceNow Solution: Cancel Button Dependent on Requested Item (Request vs Requested Item)
-------------------------------------------------
Problem
-------------------------------------------------
The Request form (sc_request) does not have the Catalog Item (cat_item) field.
The Catalog Item exists on Requested Item (sc_req_item).
A Request can contain multiple Requested Items (RITMs), so the Cancel button cannot depend directly on a single item field from the Request.
-------------------------------------------------
Option A – Place Cancel Button on Requested Item (Recommended)
-------------------------------------------------
UI Action (server-side) on table sc_req_item
Condition (Display):
current.isValidRecord() &&
current.state != 'closed_complete' &&
current.state != 'closed_incomplete' &&
current.state != 'cancelled' &&
gs.hasRole('itil');
Script:
(function cancelRITM() {
if (typeof workflow != 'undefined' && workflow.cancel) {
workflow.cancel(current);
}
current.setValue('state', 'cancelled');
current.setValue('approval', 'cancelled');
current.update();
gs.addInfoMessage('Requested Item cancelled.');
action.setRedirectURL(current);
})();
This button is item-dependent and simple to manage.
-------------------------------------------------
Option B – Keep Button on Request (sc_request) and Evaluate Child RITMs
-------------------------------------------------
B1) Single Eligible RITM Logic
Condition:
(function showOnSingleEligibleRITM() {
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request', current.sys_id);
ritm.addQuery('state', '!=', 'closed_complete');
ritm.addQuery('state', '!=', 'closed_incomplete');
ritm.addQuery('state', '!=', 'cancelled');
ritm.query();
var count = 0, only;
while (ritm.next()) { count++; only = ritm.copy(); }
if (count != 1) return false;
// Example: check item sys_id
// return (only.cat_item == 'ITEM_SYS_ID');
return gs.hasRole('itil');
})();
Script:
(function cancelSingleChild() {
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request', current.sys_id);
ritm.addQuery('state', '!=', 'closed_complete');
ritm.addQuery('state', '!=', 'closed_incomplete');
ritm.addQuery('state', '!=', 'cancelled');
ritm.query();
if (ritm.next()) {
cancelRITM(ritm);
}
action.setRedirectURL(current);
function cancelRITM(r) {
if (typeof workflow != 'undefined' && workflow.cancel) workflow.cancel(r);
r.setValue('state', 'cancelled');
r.setValue('approval', 'cancelled');
r.update();
}
})();
B2) Cancel All Eligible RITMs
Condition: at least one cancellable RITM.
Script:
(function cancelAllChildren() {
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request', current.sys_id);
ritm.addQuery('state', '!=', 'closed_complete');
ritm.addQuery('state', '!=', 'closed_incomplete');
ritm.addQuery('state', '!=', 'cancelled');
ritm.query();
var cancelled = 0;
while (ritm.next()) {
if (isItemCancellable(ritm)) {
cancelRITM(ritm); cancelled++;
}
}
gs.addInfoMessage('Cancelled ' + cancelled + ' Requested Item(s).');
action.setRedirectURL(current);
function isItemCancellable(r) {
// Put item-specific condition here
// return (r.cat_item == 'ITEM_SYS_ID');
return true;
}
function cancelRITM(r) {
if (typeof workflow != 'undefined' && workflow.cancel) workflow.cancel(r);
r.setValue('state', 'cancelled');
r.setValue('approval', 'cancelled');
r.update();
}
})();
-------------------------------------------------
Option C – Derive Primary Item on Request
-------------------------------------------------
Add a Business Rule on sc_req_item to set a field u_primary_cat_item on sc_request
(if there’s a single RITM or a business-defined “primary” one).
Then, in your Request UI Action condition, reference current.u_primary_cat_item.
-------------------------------------------------
Service Portal and Workspace Notes
-------------------------------------------------
In Service Portal: extend the request page server script to check child RITMs before exposing the cancel button.
In Workspace: use a Record UI Action or a UI Builder button calling a Scripted REST API with the same logic.
-------------------------------------------------
Summary
-------------------------------------------------
- sc_request has no item field; sc_req_item does.
- Place cancel logic on RITM if possible (Option A).
- For Request-level actions, inspect child RITMs (Option B) or derive item data (Option C).
- Choose the simplest approach matching your business need.
Key takeaway:
You cannot directly depend on the Item from the Request form because the item lives on its child RITMs. Query them or derive a field on Request to drive conditional logic.
