onSubmit client script runs when clicking “Click to add...” on a custom attachment/document field, b

kishorvanam
Mega Contributor

Hi everyone,

I have a custom table u_documentsdemo_table with a custom field u_document (type: [fill in: Document ID / Attachment / other, as shown in the dictionary entry]). On the form, this field shows a “Click to add...” link.

Requirement

I want to block the submit and show an alert (“Please attach the document before submitting”) if no document is attached, and allow the submit if a document is attached. I know a Mandatory field or UI Policy can do this, but I specifically need to implement it with an onSubmit client script for learning purposes.

What I built

An onSubmit client script (UI Type: All, Global checked, Isolate script checked) and a client-callable Script Include. Both are in the screenshots.

Client script:

function onSubmit() {
var ga = new GlideAjax('AttachmentCheck');
ga.addParam('sysparm_name', 'hasAttachment');
ga.addParam('sysparm_sys_id', g_form.getUniqueValue());
ga.getXMLWait();
var answer = ga.getAnswer();

if (answer == 'true') {
return true;
}
alert('Please attach the document before submitting.');
return false;
}



var AttachmentCheck = Class.create();
AttachmentCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
hasAttachment: function() {
var recId = this.getParameter('sysparm_sys_id');
var gr = new GlideRecord('sys_attachment');
gr.addQuery('table_sys_id', recId);
gr.query();
if (gr.hasNext()) {
return 'true';
}
return 'false';
},
type: 'AttachmentCheck'
});


What works

  • Clicking Submit with no attachment shows the alert and stops the submit.
  • Adding a file with the paperclip icon at the top, then clicking Submit, saves the record.

What does not work

  • When I click “Click to add...” on the u_document field, the alert “Please attach the document before submitting” appears immediately, and the file picker never opens. So I cannot add a file through the field at all. It behaves as if clicking the link triggers the onSubmit script.

 

 

What I already tried

  • Filtering with g_form.getActionName() to skip non-submit actions. It did not change the behavior.
  • Checking g_form.getValue('u_document') before calling GlideAjax. The alert still appears when the field is empty at click time.
  • A UI Policy making u_document mandatory works as expected, but I need to understand and solve this with onSubmit.
  • Action name shown when the link is clicked: [fill in, using a temporary script alert('Action name: ' + g_form.getActionName()); return true;, or write “no alert appeared”]


    My questions

    1. Why does clicking “Click to add...” on this field trigger the onSubmit script?
    2. How can I validate that a document is attached on Submit without blocking the field’s own “Click to add...” action?
    3. Is there a reliable way to tell a real Submit/Update click apart from the field’s internal action inside onSubmit?
    4. Does a file added through this field get stored in sys_attachment with a different table_name or table_sys_id than one added with the paperclip, especially on a new record that is not saved yet?








1 ACCEPTED SOLUTION

Hi @kishorvanam ,

When you click "New" to open a brand new form, ServiceNow immediately generates a temporary 32-character sys_id in the browser before you even type anything.

When you use the global paperclip, the system just takes your uploaded file, drops it into the sys_attachment table, and stamps it with that temporary sys_id. It doesn't care if your actual record exists yet. If you close the browser tab and never click submit, that file just becomes a hidden orphan in the database and a background scheduled job cleans it up a few days later.

The "File Attachment" field type is completely different. It acts essentially as a specialized reference field. When you add a file via that specific field, the system doesn't just upload the file; it has to grab the sys_id of the newly created attachment and save it directly into the u_document column on your custom table.

Because of how the native UI macro for that field is hardcoded, the platform cannot update a column value on a record that hasn't been committed to the database yet. To get around this, ServiceNow forces a sysverb_insert to physically create the row in your table first. Once the record actually exists, it opens the upload window, attaches the file using that ZZ_YY prefix, and finally updates the u_document column on your newly created row with the attachment's sys_id.

Basically, the paperclip is just a blind file dump using a temporary ID, while the specific field requires a real database row to establish the 1:1 field mapping.

Happy to help! If this resolved your issue, kindly mark it as the Accept Solution✅ and Helpful and close the thread 🔒 so it helps other community members too.

Warm Regards,

Deepak Sharma

Community Rising Star 2025

View solution in original post

6 REPLIES 6

Hi @kishorvanam ,

When you click "New" to open a brand new form, ServiceNow immediately generates a temporary 32-character sys_id in the browser before you even type anything.

When you use the global paperclip, the system just takes your uploaded file, drops it into the sys_attachment table, and stamps it with that temporary sys_id. It doesn't care if your actual record exists yet. If you close the browser tab and never click submit, that file just becomes a hidden orphan in the database and a background scheduled job cleans it up a few days later.

The "File Attachment" field type is completely different. It acts essentially as a specialized reference field. When you add a file via that specific field, the system doesn't just upload the file; it has to grab the sys_id of the newly created attachment and save it directly into the u_document column on your custom table.

Because of how the native UI macro for that field is hardcoded, the platform cannot update a column value on a record that hasn't been committed to the database yet. To get around this, ServiceNow forces a sysverb_insert to physically create the row in your table first. Once the record actually exists, it opens the upload window, attaches the file using that ZZ_YY prefix, and finally updates the u_document column on your newly created row with the attachment's sys_id.

Basically, the paperclip is just a blind file dump using a temporary ID, while the specific field requires a real database row to establish the 1:1 field mapping.

Happy to help! If this resolved your issue, kindly mark it as the Accept Solution✅ and Helpful and close the thread 🔒 so it helps other community members too.

Warm Regards,

Deepak Sharma

Community Rising Star 2025

Thank you @Deėpak Sharma . Summary of what I found, in case it helps others.

Setup: custom table u_documentsdemo_table with a File Attachment field u_document, and an onSubmit client script that should block Submit/Update when no file is attached.

Findings

  1. Clicking “Click to add...” saves the record immediately, before the attach-file dialog opens. If the user clicks Cancel, a record with an empty u_document has already been created and appears in the list. The field needs a real database row to store the attachment sys_id, which the paperclip does not.
  2. Inside onSubmit, g_form.getActionName() returns none for the “Click to add...” click, and sysverb_insert / sysverb_update for the real Submit/Update buttons.
  3. g_form.getValue('u_document') is empty when no file is attached, and holds the attachment sys_id when a file is attached.

What works with a client script only: skip the internal none action so the file picker still opens, and validate u_document only on real Submit/Update.

 
javascript
function onSubmit() {
    var action = g_form.getActionName();

    // "Click to add..." arrives as 'none': skip so the file picker opens
    if (action != 'sysverb_insert' && action != 'sysverb_update' && action != 'sysverb_insert_and_stay') {
        return true;
    }

    // File attached: allow submit/update
    if (g_form.getValue('u_document') != '') {
        return true;
    }

    alert('Please attach the document before submitting.');
    return false;
}

Limitation: the first auto-save triggered by “Click to add...” cannot be stopped from a client script, because blocking it would also block the file picker. So a file-less record can still be created if the user cancels the dialog. That record cannot be updated later without a file, because the alert blocks the Update.

My remaining questions

  1. Is there any other option, using an onSubmit script (or any other client-side approach), to stop the file-less record from being created by the “Click to add...” auto-save, without blocking the file picker?
  2. Is this behavior (the record being saved as soon as “Click to add...” is clicked, even if the user cancels the attach dialog) the intended functionality of the File Attachment field data type?

Marking the forced-insert explanation as the solution. Thanks again!