- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-06-2022 08:33 PM
Hi there
i have a requirement to restrict a catalog item to just one time request per user, that is once its requested and state pending or completed it cannot be requested again.
This is requested via the servicenow portal.
the attached script does not seem to work it always comes up with the message when i change user 'duplicate request cannot be submitted'
Thanks
Levino
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var ga = new GlideAjax('restrictduplicateitem');
ga.addParam('sysparm_name', 'restrictduplication');
ga.addParam('sysparm_reqfor', newValue);
ga.getXML(alertUser);
function alertUser(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer) {
g_form.showFieldMsg('requested_for', 'Duplicate request can not be submitted', 'Error');
g_form.setValue('hidden_variable', true);
} else {
g_form.hideFieldMsg('hidden_variable', true);
}
}
}
var restrictduplicateitem = Class.create();
restrictduplicateitem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
restrictduplication: function() {
var user = this.getParameter('sysparm_user');
var cat_item_id = this.getParameter('sysparm_catitem');
var gr = new GlideRecord('sc_req_item');
gr.addEncodedQuery('cat_item=' + cat_item_id + '^stateNOT IN3,4,7^request.requested_for=' + req_for);
gr.query();
if (gr.next())
return true;
else
return false;
},
type: 'restrictduplicateitem'
});
function onSubmit() {
//Type appropriate comment here, and begin script below
if (g_form.getValue('hidden_variable') == 'true') {
return false;
}
}
Thanks
Levino
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-07-2022 12:24 AM
Hi,
you don't require onSubmit
if the validation fails then clear the requested for and show error so that unless user selects correct user form cannot be submitted
try this
var restrictduplicateitem = Class.create();
restrictduplicateitem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
restrictduplication: function() {
var user = this.getParameter('sysparm_user');
var cat_item_id = this.getParameter('sysparm_catitem');
var gr = new GlideRecord('sc_req_item');
gr.addEncodedQuery('cat_item=' + cat_item_id + '^stateNOT IN3,4,7^request.requested_for=' + user);
gr.query();
return gr.hasNext();
},
type: 'restrictduplicateitem'
});
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
g_form.hideFieldMsg('requested_for', true);
if(oldValue != newValue){
var ga = new GlideAjax('restrictduplicateitem');
ga.addParam('sysparm_name', 'restrictduplication');
ga.addParam('sysparm_reqfor', newValue);
ga.getXML(alertUser);
function alertUser(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer.toString() == 'true') {
g_form.clearValue('requested_for', true);
g_form.showFieldMsg('requested_for', 'Duplicate request can not be submitted', 'Error');
}
}
}
}
Regards
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-07-2022 04:20 AM
Hi Levino,
Variable "request_for" is a variable in Service Catalog set when the form is submitted. As such, it's not possible to set onChange() script on it.
It is also not possible to use GlideAjax in onSubmit() script.
Therefore, to prevent end-user from submitting a duplicate request, create a before business rule on sc_request and sc_req_item tables.
Business rule on sc_request table
(function executeRule(current, previous /*null when async*/ ) {
var cat_item_name = 'Prevent duplicate request'; // replace with service catalog form to prevent duplicate
var grReqItem = new GlideRecord('sc_req_item');
grReqItem.addEncodedQuery('cat_item.name=' + cat_item_name + '^stateNOT IN3,4,7^request.requested_for=' + current.requested_for);
grReqItem.query();
if (grReqItem.hasNext()) {
current.setAbortAction(true);
gs.addErrorMessage('Request can only be submitted once.');
}
})(current, previous);
Business rule on sc_req_item table
(function executeRule(current, previous /*null when async*/ ) {
var cat_item_name = 'Prevent duplicate request';
var grReqItem = new GlideRecord('sc_req_item');
grReqItem.addEncodedQuery('cat_item.name=' + cat_item_name + '^stateNOT IN3,4,7^request.requested_for=' + current.requested_for);
grReqItem.query();
if (grReqItem.hasNext()) {
current.setAbortAction(true);
}
})(current, previous);
Execution result:
step 1. New submission by user
step 2: Order created
step 3: Re-create order with same request_for
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-07-2022 04:35 AM
Thanks Hitoshi
BR might be the way to go , will test and come back to update post

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-08-2022 08:20 AM
Hi Levino,
As I've explained above, the problem is with the requested_for. If a new field "requested_for" is added to the form, onChange() client script can be used. However, this "requested_for" will be different from the "requested_for" variable in the sc_req_item table.
So, the script include .addEncodedQuery() filter condition has to be modified to use the newly created requested_for variable added to the form instead of the request_for variable in sc_req_item.request.
To get the sys_id of requested_for variable on the form, open up the variable definition page for the variable requested_for and right click on the header and select sys_id.
Script Include
var restrictduplicateitem = Class.create();
restrictduplicateitem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
restrictduplication: function() {
var user = this.getParameter('sysparm_user');
var cat_item_id = 'daa58f7d9717011086d3b4b3f153af47'; // sys_id of service catalog of the form
var requested_for = '52e58f7d9717011086d3b4b3f153af52'; // sys_id of "requested_for" variable added to the form
var gr = new GlideRecord('sc_req_item');
gr.addEncodedQuery('cat_item=' + cat_item_id + '^stateNOT IN3,4,7^variables.' + requested_for + '=' + user);
gr.query();
return gr.hasNext().toString();
},
type: 'restrictduplicateitem'
});
Client Script
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
if(oldValue != newValue){
var ga = new GlideAjax('restrictduplicateitem');
ga.addParam('sysparm_name', 'restrictduplication');
ga.addParam('sysparm_user', newValue);
ga.getXML(alertUser);
function alertUser(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer == 'true') {
g_form.clearValue('requested_for', true);
g_form.showFieldMsg('requested_for', 'Duplicate request can not be submitted', 'error');
}
}
}
}
Execution
case 1:New requested_for user (no duplicate)
case 2: Duplicate requested_for user
Note that by default, when submitting the form from Service Portal, ServiceNow will show a dialog box to enter Requested For user. That's the reason I've recommended to use Business Rule instead of adding request_for on the form.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-08-2022 08:33 AM
Almost forgot, Field "Requested For" must be made Mandatory or else end-user will be able to submit the form without requested_for field being entered.
Script Include
- Change variable "req_for" in addEncodedQuery to "user"
- Changed "request.requested_for" in addEncodedQuery to "variables.' + requested_for"
- Changed variable "cat_item_id" value to be fixed instead of getting it from parameter because it's static
- Added variable "requested_for"
- Converted return value to String (i.e. added .toString())
Client Script
- Change "Error" to "error" in .showFieldMsg() because JavaScript is case sensitive
- Delete .hideFieldMsg() because it's not needed
- Change addParam parameter name from "sysparm_reqfor" to "sysparm_user" to match Script Include

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-08-2022 07:04 PM
Script Include can be written as below to eliminate using finding sys_id of service catalog and sys_id of variable name.
var restrictduplicateitem = Class.create();
restrictduplicateitem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
restrictduplication: function() {
var user = this.getParameter('sysparm_user');
var catName = 'Prevent duplicate request'; // name of service catalog
var variableName = 'requested_for'; // name of variable
var grCat = new GlideRecord('sc_cat_item');
if (grCat.get('name', catName)) {
var cat_item_id = grCat.getValue('sys_id');
var grItemOption = new GlideRecord('item_option_new');
grItemOption.addQuery('cat_item.name', catName);
grItemOption.addQuery('name', variableName);
grItemOption.query();
if (grItemOption.next()) {
var requested_for = grItemOption.getValue('sys_id');
var gr = new GlideRecord('sc_req_item');
gr.addEncodedQuery('cat_item=' + cat_item_id + '^stateNOT IN3,4,7^variables.' + requested_for + '=' + user);
gr.query();
return gr.hasNext().toString();
}
}
return 'false';
},