- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-06-2025 10:22 PM
Dear experts,
My client would like to have a bulk attest button just like the bulk approve button in the approval table where they can select multiple records in the list then in the list menu they have an approve button to approve all the things required in servicenow. So their requirements are without going into the attestation form and fill in the attestation form which only have two fields
1. Is the control implemented (Yes or No) - Mandatory
2. Explanation
They would like to have the ui action in the list menu which is approve where when click approve it will help them fill in the first question is yes and the explanation field is just leave it blank then changed the state of attestation form to complete. I have tried my own approach to create a new approve ui action list menu and a script include below:
UI Action Script:
function onBulkApprove() {
var selectedRecords = g_list.getChecked();
if (selectedRecords.length === 0) {
alert("Please select at least one record.");
return;
}
var ga = new GlideAjax('global.BulkAttestationProcessor');
ga.addParam('sysparm_name', 'processBulkAttestation');
ga.addParam('sysparm_sys_ids', selectedRecords.join(','));
ga.getXMLAnswer(function(response) {
alert(response); // Show confirmation
g_list.refresh(); // Refresh list
});
}
Script Include:
var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {
processBulkAttestation: function() {
var sysIds = this.getParameter('sysparm_sys_ids').split(',');
var count = 0;
// Get the metric sys_id for the "Is the control implemented?" question
var metricGr = new GlideRecord('asmt_metric');
metricGr.addQuery('name', 'Is the control implemented?');
metricGr.query();
if (!metricGr.next()) {
return 'Metric "Is the control implemented?" not found.';
}
var metricSysId = metricGr.getUniqueValue();
for (var i = 0; i < sysIds.length; i++) {
var instanceId = sysIds[i];
var instanceGr = new GlideRecord('asmt_assessment_instance');
if (!instanceGr.get(instanceId)) continue;
// Check if metric result already exists
var resultGr = new GlideRecord('asmt_metric_result');
resultGr.addQuery('metric', metricSysId);
resultGr.addQuery('instance', instanceId);
resultGr.query();
var resultExists = false;
while (resultGr.next()) {
resultExists = true;
resultGr.setValue('actual_value', 1);
resultGr.update();
count++;
}
// If no result exists, create one manually
if (!resultExists) {
var newResult = new GlideRecord('asmt_metric_result');
newResult.initialize();
newResult.setValue('metric', metricSysId);
newResult.setValue('instance', instanceId);
newResult.setValue('actual_value', 1);
newResult.insert();
count++;
}
// Mark the instance as complete
instanceGr.setValue('state', 'complete');
instanceGr.update();
}
return count + " attestation(s) approved.";
}
});
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-06-2025 11:48 PM
Hi @ChuanYanF
You need to set the survey reponse in "asmt_assessment_instance_question" table.
I've modified your script and tested it in my PDI. It's working as expected. Please review and modify as required.
UI action:
function onBulkApprove() {
var selectedRecords = g_list.getChecked();
if (selectedRecords.length === 0) {
alert("Please select at least one record.");
return;
} else {
var ga = new GlideAjax('BulkAttestationProcessor');
ga.addParam('sysparm_name', 'processBulkAttestation');
ga.addParam('sysparm_sys_ids', selectedRecords);
ga.getXMLAnswer(function(response) {
alert(response); // Show confirmation
g_list.refresh(); // Refresh list
});
}
}
Script include:
var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {
processBulkAttestation: function() {
var sysIds = this.getParameter('sysparm_sys_ids').split(',');
var count = 0;
// Get the metric sys_id for the "Is the control implemented?" question
var metricGr = new GlideRecord('asmt_metric');
metricGr.addQuery('name', 'Is the control implemented?');
metricGr.query();
if (!metricGr.next()) {
return 'Metric "Is the control implemented?" not found.';
} else {
var metricSysId = metricGr.getUniqueValue();
}
for (var i = 0; i < sysIds.length; i++) {
var instanceId = sysIds[i];
var instanceGr = new GlideRecord('asmt_assessment_instance');
if (!instanceGr.get(instanceId)) continue;
// Check if metric result already exists
var resultGr = new GlideRecord('asmt_assessment_instance_question'); //UPDATED
resultGr.addQuery('metric', metricSysId);
resultGr.addQuery('instance', instanceId);
resultGr.query();
var resultExists = false;
while (resultGr.next()) {
resultExists = true;
resultGr.setValue('value', 1);
resultGr.update();
count++;
}
// Mark the instance as complete
instanceGr.setValue('state', 'complete');
instanceGr.update();
}
return count + " attestation(s) approved.";
},
type: 'BulkAttestationProcessor'
});
Regards,
Siva
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-06-2025 10:55 PM
so where are you asking the input? I couldn't see that
where are you stuck?
If my response helped please mark it correct and close the thread so that it benefits future readers.
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-06-2025 11:04 PM
I dunno why it is not working, the approve ui action is under the list menu but when I click it nothing happens. So I dont know if my script is wrong or it is not doable?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-06-2025 11:34 PM
did you debug if script include is getting called?
If my response helped please mark it correct and close the thread so that it benefits future readers.
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-06-2025 11:48 PM
Hi @ChuanYanF
You need to set the survey reponse in "asmt_assessment_instance_question" table.
I've modified your script and tested it in my PDI. It's working as expected. Please review and modify as required.
UI action:
function onBulkApprove() {
var selectedRecords = g_list.getChecked();
if (selectedRecords.length === 0) {
alert("Please select at least one record.");
return;
} else {
var ga = new GlideAjax('BulkAttestationProcessor');
ga.addParam('sysparm_name', 'processBulkAttestation');
ga.addParam('sysparm_sys_ids', selectedRecords);
ga.getXMLAnswer(function(response) {
alert(response); // Show confirmation
g_list.refresh(); // Refresh list
});
}
}
Script include:
var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {
processBulkAttestation: function() {
var sysIds = this.getParameter('sysparm_sys_ids').split(',');
var count = 0;
// Get the metric sys_id for the "Is the control implemented?" question
var metricGr = new GlideRecord('asmt_metric');
metricGr.addQuery('name', 'Is the control implemented?');
metricGr.query();
if (!metricGr.next()) {
return 'Metric "Is the control implemented?" not found.';
} else {
var metricSysId = metricGr.getUniqueValue();
}
for (var i = 0; i < sysIds.length; i++) {
var instanceId = sysIds[i];
var instanceGr = new GlideRecord('asmt_assessment_instance');
if (!instanceGr.get(instanceId)) continue;
// Check if metric result already exists
var resultGr = new GlideRecord('asmt_assessment_instance_question'); //UPDATED
resultGr.addQuery('metric', metricSysId);
resultGr.addQuery('instance', instanceId);
resultGr.query();
var resultExists = false;
while (resultGr.next()) {
resultExists = true;
resultGr.setValue('value', 1);
resultGr.update();
count++;
}
// Mark the instance as complete
instanceGr.setValue('state', 'complete');
instanceGr.update();
}
return count + " attestation(s) approved.";
},
type: 'BulkAttestationProcessor'
});
Regards,
Siva