Need Help: Make Attachment Mandatory on submission Only When Subject Person’s Country = India

NowNinja727
Mega Contributor
Hi Community,

I’m working on a requirement for a record producer in Service Portal where:
  • 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:

  1. 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).
  2. DOM Manipulation Approach
    • Used document.getElementsByClassName('get-attachment') for Service Portal and $j("li.attachment_list_items") for native UI.
  3. 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.
  4. 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.

 

Any sample code or guidance would be greatly appreciated!

Thanks!
3 ACCEPTED SOLUTIONS

@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.

View solution in original post

Aniket Chavan
Tera Sage
Tera Sage

Hi @NowNinja727 ,

I completely understand the pain here , especially when trying to mix onSubmit Client Scripts + attachment checks + server-side country validation. I've faced something very similar recently, and the biggest challenge was exactly what you’re seeing:

  • onSubmit timing issues

  • GlideAjax getXML wait problems

  • attachment DOM logic not syncing fast enough

  • submission blocked even after attaching a file

There are multiple solution patterns available, but if you’re open to a simpler and more reliable approach, I’d strongly suggest using an Attachment variable instead of relying on the default portal attachment panel.

 

  • You can make the attachment variable mandatory only when Subject Person's country = India

  • Just use an onChange script on Subject Person to evaluate the country, you can use here getReference

  • If country = India → make attachment field mandatory + show any message you want and also you can show this variable only if subject person is from India for other you can keep hidden

This avoids the entire async onSubmit/GlideAjax complexity.

One thing to note:


Attachment variables do NOT automatically attach files to the target record, so add this in your record producer script section:

new global.VariableUtil().copyAttachment(producer.<variableName>, '<tableName>', current.sys_id);

 

This approach should save you a lot of time and frustration.

 

🔹 Please mark Correct if this solves your query, and 👍 Helpful if you found the response valuable.

 

Best regards,
Aniket Chavan
🏆 ServiceNow MVP 2025 | 🌟 ServiceNow Rising Star 2024

View solution in original post

 

@NowNinja727 , I was actually about to share another improvement idea, but while drafting I noticed @John Gilmore  already mentioned something similar , and I definitely agree with him.

 

If you haven’t considered it yet, I think the most efficient direction is:

Create a variable to store Subject Person Country

  • Auto-populate based on Subject Person reference

  • Mark it as hidden, so that it will not show up on the portal.....

 Then apply validation using that variable

This gives you a clean and consistent condition to check instead of relying on getReference() timing or any script inlcude or anything

 

Below is a sample onSubmit script you can adapt to your variable names:

function onSubmit() {
    var country = g_form.getValue('subject_person_country');

    if (country === 'India') {
        var attachmentCount = getSCAttachmentCount(); // Portal attachment count API

        if (attachmentCount <= 0) {
            g_form.addErrorMessage(
                'Please add at least one attachment before submitting this request.'
            );
            return false;
        }
    }
}

 

This should work smoothly, without the async GlideAjax or DOM dependency.

 

Give it a try and let us know how it goes , if something still blocks, we can troubleshoot further. 🙌

 

🔹 Please mark Correct if this solves your query, and 👍 Helpful if you found the response valuable.

 

Best regards,
Aniket Chavan
🏆 ServiceNow MVP 2025 | 🌟 ServiceNow Rising Star 2024

 

View solution in original post

13 REPLIES 13

pavani_paluri
Tera Guru
Tera Guru

Hi @NowNinja727 ,

 Please try below code and let me know if that works

var bypassCheck = false;

function onSubmit() {
    if (bypassCheck) {
        return true; // Allow submit after Ajax passes
    }

    if (g_form.getValue('u_type_mitarbeiter') == 'u_neuer') {
        try { // Works in non-portal UI
            var cat_id = g_form.getValue('sysparm_item_guid');

            var ajax = new GlideAjax('CatalogUtilsAjax'); // your Script Include
            ajax.addParam('sysparm_name', 'hasAttachment');
            ajax.addParam('sysparm_cat_id', cat_id);

            ajax.getXML(ajaxResponse);

            // Stop first submit attempt; wait for async
            return false;
        } catch (e) { // For Service Portal
            var count = getSCAttachmentCount();
            if (count <= 0) {
                alert('You must attach a document to submit');
                return false;
            }
        }
    }
}

// Callback at root level
function ajaxResponse(response) {
    var answer = response.responseXML.documentElement.getAttribute('answer');

    if (answer == 'false') {
        g_form.addErrorMessage('You must attach a document to submit');
    } else {
        bypassCheck = true; // prevent infinite loop
        g_form.save();      // submit the form
    }
}
 
Mark it helpful if this helps you to understand. Accept solution if this give you the answer you're looking for
Kind Regards,
Pavani P

John Gilmore
Giga Guru

Your use case isn't simple given that you need the functionality in both Service Portal and Mobile UI which don't support the same methods. So you would need to approach this in a way that doesn't use many of the standard functions you'll find related to Service Portal.

 

In order to apply this logic across these two UIs you will need to use a business rule with the when to apply set to before-insert. I don't know of another way to apply it to both UIs with one configuration. You would start with a  condition that Subject Person's country is India. If this evaluates to true then check the attachments.

You stated this is occurring on a record producer so the query on sys_attachment works since you are in a before-insert business rule. You would need to query sys_attachment where table_name is your table and table_sys_id is current.sys_id. This would return a count of attachments which could then be used inside the if condition to either cancel the insert or allow it to proceed.

Thanks for the reply @John Gilmore , please refer my reply below from @Sandeep Rajput 's thread and suggest me anything if you have anything, thank you so much!

Sandeep Rajput
Tera Patron
Tera Patron

@NowNinja727 Ideally a combination of GlideAjax + Script include should work here. You can simply check the subject person country and see if they uploaded an attachment by querying the sys_attachment table. However, if this is not working then there must be something wrong with the logic here.

 

Could you please share your client script and script include code here to suggest the improvements.