Need Help: Make Attachment Mandatory on submission Only When Subject Person’s Country = India
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11 hours ago
- There is a reference variable called Subject Person (points to sys_user).
- If the selected user’s country = India, then at least one attachment must be added before submission.
- If the country is not India, submission should proceed without attachment.
What We Tried So Far:
- OnSubmit Client Script using getReference()
- We fetched the country from the Subject Person record and then checked attachments using Angular DOM (scope.attachments.length).
- Issue: Works partially, but fails when attachments are added (still blocks submission).
- DOM Manipulation Approach
- Used document.getElementsByClassName('get-attachment') for Service Portal and $j("li.attachment_list_items") for native UI.
- GlideAjax + Script Include
- Created a Script Include (CheckAttachment) to check attachments and country.
- Tried multiple patterns (pause submission, resubmit after validation).
- Issue: Logic works for blocking when no attachment, but still blocks even after attachment is added.
- System Property Approach
- Attempted to make country configurable via system property and validate in Script Include.
- Issue: Still facing the same problem with attachment validation.
Where We Are Stuck:
- We need a robust solution that works in Service Portal and Mobile UI.
- Ideally, we want one GlideAjax call that:
- Gets the country.
- Checks if attachments exist for the current record.
- Returns true/false so we can allow or block submission.
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
9 hours ago
Hi Sandeep,
Thanks for your response! Here are the approaches I tried and where I faced issues:
1. Partially Working Code (Using getReference() for Country Check)
This script correctly identifies if the Subject Person’s country is India and blocks submission when no attachment exists. It also allows submission when the country is not India.\ Issue: Even after adding attachments, the form still blocks submission for India users.
function onSubmit() {
if (gscratchpad && gscratchpad.isFormValid) return true;
// Fetch full user record for hrsubjectperson
gform.getReference('hrsubjectperson', function(userRecord) {
var country = (userRecord.ucountry || '').toLowerCase(); // Adjust field name if needed
if (country === 'india') {
// Check if attachments exist in Service Portal
var attachmentCount = getPortalAttachmentCount();
if (attachmentCount === 0) {
gform.addErrorMessage('Attachment is mandatory when the subject person is from India.');
return false; // Stop submission
}
}
// ✅ For non-India OR validation passed → resubmit
gscratchpad.isFormValid = true;
gform.submit('submit');
});
return false; // Pause initial submission until callback completes
}
// Helper for Service Portal attachment count
function getPortalAttachmentCount() {
try {
var scope = angular.element("#sccatitem"). var scope = angular.element("#sccat_item").scope();
if (scope && scope.attachments) {
return scope.attachments.length;
}
} catch (e) {
return 0; // Default to 0 if error
}
2. GlideAjax + Script Include Approach
Here I combined the client script with a Script Include to check both conditions (country and attachment) server-side.\ Issue: Validation works, but the form does not resubmit correctly after the async call. It either loops infinitely or does nothing.
Client Script:
function onSubmit() {
if (gscratchpad && gscratchpad.isFormValid) return true;
var subjectPerson = gform.getValue('hrsubjectperson'); // Replace with your variable name
if (!subjectPerson) {
return true; // No subject person → allow submission
}
var ga = new GlideAjax('CheckAttachment');
ga.addParam('sysparmname', 'validateIndiaAttachment');
ga.addParam('sysparmpersonsysid', subjectPerson);
ga.addParam('sysparmtable', gform.getTableName());
ga.addParam('sysparmsysid', gform.getUniqueValue());
ga.getXMLAnswer(function(response) {
if (response === 'false') {
gform.addErrorMessage('Attachment is mandatory when the Subject Person is from India.');
return false; // Stop submission
}
// ✅ Validation passed → resubmit once
gscratchpad = gscratchpad || {};
gscratchpad.isFormValid = true;
var actionName = gform.getActionName();
gform.submit(actionName); // Re-submit after validation
});
return false; // Pause initial submission until callback completes
}
Script Include:
var CheckAttachment = Class.create();
CheckAttachment.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
validateIndiaAttachment: function() {
var personSysId = this.getParameter('sysparmpersonsysid');
var tableName = this.getParameter('sysparmtable');
var recordSysId = this.getParameter('sysparmsysid');
// Get country of Subject Person
var country = '';
var userGR = new GlideRecord('sysuser'); // Adjust table if needed
if (userGR.get(personSysId)) {
country = userGR.getValue('ucountry'); // Adjust field name if needed
}
// If country is India, check attachments
if (country && country.toLowerCase() === 'india') {
var attachGR = new GlideRecord('sysattachment');
attachGR.addQuery('tablename', tableName);
attachGR.addQuery('tablesysid', recordSysId);
attachGR.query();
if (!attachGR.hasNext()) {
return 'false'; // No attachment
}
}
return 'true'; // Either not India OR attachment exists
},
type: 'CheckAttachment '
});
Could you please help me with the code,
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
9 hours ago
@NowNinja727 Please update the GlideAjax approach as follows.
Client Script:
function onSubmit() {
if (g_scratchpad && g_scratchpad.isFormValid) return true;
var subjectPerson = g_form.getValue('hrsubjectperson'); // Replace with your variable name
if (!subjectPerson) {
return true; // No subject person → allow submission
}
var ga = new GlideAjax('CheckAttachment');
ga.addParam('sysparm_name', 'validateIndiaAttachment');
ga.addParam('sysparm_personsysid', subjectPerson);
ga.addParam('sysparm_table', g_form.getTableName());
ga.addParam('sysparm_sysid', g_form.getUniqueValue());
ga.getXMLAnswer(function(response) {
if (response === 'false') {
g_form.addErrorMessage('Attachment is mandatory when the Subject Person is from India.');
return false; // Stop submission
}
// ✅ Validation passed → resubmit once
g_scratchpad = g_scratchpad || {};
g_scratchpad.isFormValid = true;
var actionName = g_form.getActionName();
g_form.submit(actionName); // Re-submit after validation
});
return false; // Pause initial submission until callback completes
}
Script Include:
var CheckAttachment = Class.create();
CheckAttachment.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
validateIndiaAttachment: function() {
var personSysId = this.getParameter('sysparm_personsysid');
var tableName = this.getParameter('sysparm_table');
var recordSysId = this.getParameter('sysparm_sysid');
// Get country of Subject Person
var country = '';
var userGR = new GlideRecord('sys_user'); // Adjust table if needed
if (userGR.get(personSysId)) {
country = userGR.getValue('country'); // Adjust field name if needed
}
// If country is India, check attachments
if (country && country.name.toLowerCase() === 'india') {
var attachGR = new GlideRecord('sys_attachment');
attachGR.addQuery('table_name', tableName);
attachGR.addQuery('table_sys_id', recordSysId);
attachGR.query();
if (!attachGR.hasNext()) {
return 'false'; // No attachment
}
}
return 'true'; // Either not India OR attachment exists
},
type: 'CheckAttachment '
});
For more information, please refer to https://www.servicenow.com/community/developer-blog/how-to-async-glideajax-in-an-onsubmit-script/ba-...
Hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 hours ago - last edited 4 hours ago
@NowNinja727
I don't know that you can use a scripted method and have it work on both the Service Portal and in Mobile UI. Even if you can pass the necessary info to the Glide Ajax to lookup the attachments the Mobile UI doesn't execute onChange and onLoad client scripts the same way so you would need separate configurations for both.
If you don't want to use a business rule then I think you would need to use an attachment variable on the Record Producer instead of just turning on attachments. Create an Attachment variable on the record producer then use Catalog UI Policy with a UI Policy Action to make it required and visible. This piece would be respected and applied by both the Mobile UI and Service Portal.
In order to do this on both the Service Portal and the Mobile UI you would need to surface the country of the selected Subject Person as a variable in the Record Producer. Once the variable exists you could populate it on the Service Portal side with an onChange script and on the Mobile UI side you would need to use a mobile script or might be able to use a data item lookup. You would then be able to reference the value of this variable in your condition on the Catalog UI Policy.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 hours ago
In portal it can be achieved by messing around with the scope of the catalog item widget and $apply will cause a digest cycle so you get the asterisk on the attachment widget. This is not good practice development of course but will likely be quite robust. This should work in the mobile app as last I checked it just used the catalog item page me_sc_cat_item with the same SC Catalog Item widget. I did not test it on mobile though
Onchange client script:
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
const catitemScope = this.angular.element("#sc_cat_item").scope();
if (newValue == "india") {
catitemScope.data.sc_cat_item.mandatory_attachment = true;
} else {
catitemScope.data.sc_cat_item.mandatory_attachment = false;
}
catitemScope.$apply()
}Instead of storing the country value in a variable you can just do a glideajax to check the country server-side.