- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
I had created two on change client scripts on incident table.
the requirement is:
case1: when initially creating incident if the business service is field services the assignment group should not auto populate
case2: when the business service is other than business service the assignment group should automatically populate based on service offering
cae3: when the other business service already existing incident we are changing into business service the assignment group should update the previous assignment group.
I had achieved this through on change client scripts on business service and service offering
on change client script for business service:
these scripts are executing as expected in classic Ui. but I want this to execute in service operation workspace (sow) also.
I had kept Ui type =All and also tried by removing global checkbox and setting view as sow but it is not worked.
Also tried business rule, script include also it was not worked.
Please help me with the solution that should work in service operation workspace.
Thanks in Advance!
Thanks & Regards,
Abhishek.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
so what debugging did you do?
did you try adding alert in few places in your client script?
did you check GlideAjax got value when script ran in workspace?
💡 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
a week ago
Making Client Scripts Work in Service Operations Workspace (SOW)
What changes for Workspace
1. Use “Form Client Scripts” with UI Type = All (or Workspace)
- Open each client script → set UI type to All (or Workspace on newer releases).
- Scope them to the Incident table and the specific fields (business_service, service_offering).
2. Don’t rely on g_scratchpad or DOM timing hacks
- In Workspace, g_scratchpad is not guaranteed on the client.
- Avoid setTimeout (refqual timing differs in Workspace).
- Use a hidden field to track the “previous assignment group” (e.g., u_prev_assignment_group), and keep all logic event-driven.
3. GlideAjax works in Workspace
- Make sure your Script Include is Client callable and returns a sys_id for the group.
- Keep it in the same scope (or allow cross-scope) as the incident form.
Minimal, workspace-safe design
Hidden field:
Add a string/reference field on Incident: u_prev_assignment_group (not mandatory to show on the form).
1) onLoad Client Script (Form → onLoad)
Purpose: remember the starting AG when editing an existing record (supports your “case3”).
function onLoad() {
var ag = g_form.getValue('assignment_group');
if (ag)
g_form.setValue('u_prev_assignment_group', ag);
}
2) onChange – Business Service
If BS == Field Services → restore previous AG (or clear if none).
Else, if there’s a Service Offering → populate via GlideAjax. No setTimeout, no g_scratchpad.
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading) return;
var FIELD_SERVICE_SYSID = '516aad7347e02650e9753cc7536d4313';
if (newValue === FIELD_SERVICE_SYSID) {
var prev = g_form.getValue('u_prev_assignment_group');
if (prev) {
g_form.setValue('assignment_group', prev);
} else {
g_form.clearValue('assignment_group');
}
return;
}
var so = g_form.getValue('service_offering');
if (!so) {
g_form.clearValue('assignment_group');
return;
}
var ga = new GlideAjax('AutoPopulateUtils');
ga.addParam('sysparm_name', 'getSupportGroupForOffering');
ga.addParam('sysparm_offering', so);
ga.getXMLAnswer(function(resp) {
if (resp) {
g_form.setValue('assignment_group', resp);
g_form.setValue('u_prev_assignment_group', resp);
} else {
g_form.clearValue('assignment_group');
}
});
}
3) onChange – Service Offering
Skip if BS == Field Services. Otherwise auto-populate via GlideAjax (no timers).
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;
var FIELD_SERVICE_SYSID = '516aad7347e02650e9753cc7536d4313';
if (g_form.getValue('business_service') === FIELD_SERVICE_SYSID) {
return;
}
if (!newValue) {
g_form.clearValue('assignment_group');
return;
}
var ga = new GlideAjax('AutoPopulateUtils');
ga.addParam('sysparm_name', 'getSupportGroupForOffering');
ga.addParam('sysparm_offering', newValue);
ga.getXMLAnswer(function(ans) {
if (ans) {
g_form.setValue('assignment_group', ans);
g_form.setValue('u_prev_assignment_group', ans);
} else {
g_form.clearValue('assignment_group');
}
});
}
This satisfies:
Case1 (BS = Field Services → do not autopopulate; restore or clear),
Case2 (other BS → autopopulate from Service Offering),
Case3 (switching an existing Incident to Field Services → restore previous group).
Script Include (server) – client callable
var AutoPopulateUtils = Class.create();
AutoPopulateUtils.prototype = {
initialize: function() {},
getSupportGroupForOffering: function() {
var offeringId = this.getParameter('sysparm_offering');
var grp = '';
if (offeringId) {
var so = new GlideRecord('service_offering');
if (so.get(offeringId)) {
grp = so.u_default_assignment_group + '';
}
}
return grp;
},
type: 'AutoPopulateUtils'
};
Make sure:
- Client callable = true
- Returns a sys_id of the group
Workspace check-list
- Client Scripts type: Form – onChange / onLoad
- UI type: All (or Workspace)
- Hidden field u_prev_assignment_group present on the form
- Script Include: client callable, same scope
- No DOM / setTimeout; everything event-driven
Extra hardening (optional)
- Add a UI Policy to make assignment_group read-only when BS = Field Services.
- Add a Business Rule (server) as a safeguard to enforce same logic on API/inline edits.
Summary
With these changes:
- Your scripts now run in Service Operations Workspace as well as Classic UI.
- You eliminate timing and scratchpad issues.
- Logic remains consistent across UI frameworks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
so what debugging did you do?
did you try adding alert in few places in your client script?
did you check GlideAjax got value when script ran in workspace?
💡 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
a week ago
Making Client Scripts Work in Service Operations Workspace (SOW)
What changes for Workspace
1. Use “Form Client Scripts” with UI Type = All (or Workspace)
- Open each client script → set UI type to All (or Workspace on newer releases).
- Scope them to the Incident table and the specific fields (business_service, service_offering).
2. Don’t rely on g_scratchpad or DOM timing hacks
- In Workspace, g_scratchpad is not guaranteed on the client.
- Avoid setTimeout (refqual timing differs in Workspace).
- Use a hidden field to track the “previous assignment group” (e.g., u_prev_assignment_group), and keep all logic event-driven.
3. GlideAjax works in Workspace
- Make sure your Script Include is Client callable and returns a sys_id for the group.
- Keep it in the same scope (or allow cross-scope) as the incident form.
Minimal, workspace-safe design
Hidden field:
Add a string/reference field on Incident: u_prev_assignment_group (not mandatory to show on the form).
1) onLoad Client Script (Form → onLoad)
Purpose: remember the starting AG when editing an existing record (supports your “case3”).
function onLoad() {
var ag = g_form.getValue('assignment_group');
if (ag)
g_form.setValue('u_prev_assignment_group', ag);
}
2) onChange – Business Service
If BS == Field Services → restore previous AG (or clear if none).
Else, if there’s a Service Offering → populate via GlideAjax. No setTimeout, no g_scratchpad.
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading) return;
var FIELD_SERVICE_SYSID = '516aad7347e02650e9753cc7536d4313';
if (newValue === FIELD_SERVICE_SYSID) {
var prev = g_form.getValue('u_prev_assignment_group');
if (prev) {
g_form.setValue('assignment_group', prev);
} else {
g_form.clearValue('assignment_group');
}
return;
}
var so = g_form.getValue('service_offering');
if (!so) {
g_form.clearValue('assignment_group');
return;
}
var ga = new GlideAjax('AutoPopulateUtils');
ga.addParam('sysparm_name', 'getSupportGroupForOffering');
ga.addParam('sysparm_offering', so);
ga.getXMLAnswer(function(resp) {
if (resp) {
g_form.setValue('assignment_group', resp);
g_form.setValue('u_prev_assignment_group', resp);
} else {
g_form.clearValue('assignment_group');
}
});
}
3) onChange – Service Offering
Skip if BS == Field Services. Otherwise auto-populate via GlideAjax (no timers).
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;
var FIELD_SERVICE_SYSID = '516aad7347e02650e9753cc7536d4313';
if (g_form.getValue('business_service') === FIELD_SERVICE_SYSID) {
return;
}
if (!newValue) {
g_form.clearValue('assignment_group');
return;
}
var ga = new GlideAjax('AutoPopulateUtils');
ga.addParam('sysparm_name', 'getSupportGroupForOffering');
ga.addParam('sysparm_offering', newValue);
ga.getXMLAnswer(function(ans) {
if (ans) {
g_form.setValue('assignment_group', ans);
g_form.setValue('u_prev_assignment_group', ans);
} else {
g_form.clearValue('assignment_group');
}
});
}
This satisfies:
Case1 (BS = Field Services → do not autopopulate; restore or clear),
Case2 (other BS → autopopulate from Service Offering),
Case3 (switching an existing Incident to Field Services → restore previous group).
Script Include (server) – client callable
var AutoPopulateUtils = Class.create();
AutoPopulateUtils.prototype = {
initialize: function() {},
getSupportGroupForOffering: function() {
var offeringId = this.getParameter('sysparm_offering');
var grp = '';
if (offeringId) {
var so = new GlideRecord('service_offering');
if (so.get(offeringId)) {
grp = so.u_default_assignment_group + '';
}
}
return grp;
},
type: 'AutoPopulateUtils'
};
Make sure:
- Client callable = true
- Returns a sys_id of the group
Workspace check-list
- Client Scripts type: Form – onChange / onLoad
- UI type: All (or Workspace)
- Hidden field u_prev_assignment_group present on the form
- Script Include: client callable, same scope
- No DOM / setTimeout; everything event-driven
Extra hardening (optional)
- Add a UI Policy to make assignment_group read-only when BS = Field Services.
- Add a Business Rule (server) as a safeguard to enforce same logic on API/inline edits.
Summary
With these changes:
- Your scripts now run in Service Operations Workspace as well as Classic UI.
- You eliminate timing and scratchpad issues.
- Logic remains consistent across UI frameworks.
