How to Dynamically Show/Hide and Require Attachments in a Record Producer

Nayara Gomes da
Tera Contributor

 

While working on a Record Producer requirement, I needed to dynamically control the standard ServiceNow attachment button based on a user's selection.

At first, it sounded like a simple requirement. However, I spent quite some time looking for a clear way to implement it.

I searched through the ServiceNow Community and other available resources and found several discussions about hiding attachments, making attachments mandatory, and working with the standard attachment component. However, I couldn't find a complete example covering the exact behavior I needed.

The requirement was to:

  • Hide the standard attachment button by default.
  • Show it dynamically based on a variable selection.
  • Require at least one attachment only when that condition is met.
  • Continue using the native ServiceNow attachment functionality.
  • Avoid creating a custom attachment component.

After some investigation and testing, I was able to get this working in Employee Center.

Since the solution was not as straightforward to find as I initially expected, I decided to document the complete approach here. Hopefully, this can save some time for anyone facing a similar requirement.


The Requirement

In this scenario, we have a Record Producer with a variable that determines whether supporting documentation is required.

For this example, let's call the variable:

 

 
question_tipo_solicitacao
 

When the user selects the option whose value is:

 

 
request_exception
the attachment button should become visible and at least one attachment should be required before the request can be submitted.

For any other value, the attachment button should remain hidden and the user should be able to submit without attaching a document.

The expected behavior is:

Variable value Attachment button Attachment required
request_exceptionVisibleYes
Any other valueHiddenNo
EmptyHiddenNo

The important part of the requirement is that we still want to use the standard ServiceNow attachment component.


Understanding the Problem

One of the confusing parts of this requirement is that there are different ways to control attachments in ServiceNow, but they solve slightly different problems.

For example, disabling attachments entirely is not the same as hiding the attachment button.

Likewise, configuring attachments as mandatory at the Record Producer level does not solve the requirement when attachments should only be mandatory under a specific condition.

What we actually need is:

 

 
Keep attachments enabled
        ↓
Control the button visibility
        ↓
Validate the attachment condition on submit
 

That distinction is what made the solution work.


1. Keep the Native Attachment Functionality Enabled

The first step is important: do not disable the attachment functionality itself.

In my scenario, attachments remained enabled:

 

 
no_attachment_v2 = false
 

This ensures that ServiceNow still renders and manages its standard attachment component.

We are not removing the attachment functionality.

Instead, we are controlling whether the user can see the attachment button.

This allows us to keep all the native ServiceNow behavior for uploading and managing attachments.


2. Identifying the Standard Attachment Button

After inspecting the rendered Employee Center page, I found that the standard attachment button was represented by:

 

 
sp-attachment-button
 

This means we can locate the component using:

 
this.document.querySelector('sp-attachment-button');

From there, we can dynamically control its visibility.

To avoid repeating this logic, we can create a small helper function:

 

 
function toggleAttachmentButton(show) {
    var attachmentButton =
        this.document.querySelector('sp-attachment-button');

    if (!attachmentButton) {
        return;
    }

    attachmentButton.style.display = show ? '' : 'none';
}
 

When show is true, the standard attachment button is displayed.

When show is false, it is hidden.


3. Hide or Show the Attachment Button on Load

Using only an onChange Catalog Client Script is not enough.

For example, if the Record Producer loads with a value already populated, the attachment button needs to reflect that value immediately.

For this reason, I also used an onLoad Catalog Client Script:

 

 
function onLoad() {
    var value =
        g_form.getValue('question_tipo_solicitacao');

    toggleAttachmentButton(value === 'request_exception');
}

function toggleAttachmentButton(show) {
    var attachmentButton =
        this.document.querySelector('sp-attachment-button');

    if (!attachmentButton) {
        return;
    }

    attachmentButton.style.display = show ? '' : 'none';
}
 

When the form loads, the script checks the controlling variable.

If its value is request_exception, the attachment button is displayed.

Otherwise, it remains hidden.


4. Dynamically Show or Hide the Button

Next, create an onChange Catalog Client Script for the controlling variable:

 

 
question_tipo_solicitacao
 

The script is:

 
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading) {
        return;
    }

    toggleAttachmentButton(
        newValue === 'request_exception'    );
}

function toggleAttachmentButton(show) {
    var attachmentButton =
        this.document.querySelector('sp-attachment-button');

    if (!attachmentButton) {
        return;
    }

    attachmentButton.style.display = show ? '' : 'none';
}
 

Now the behavior becomes dynamic:

 
User selects request_exception
        ↓
Attachment button appears
 

And:

 
User selects another option
        ↓
Attachment button disappears
 

Notice that we are still not disabling attachments.

We are only controlling the visibility of the standard attachment component.


5. Make the Attachment Conditionally Mandatory

At this point, the attachment button behaves correctly, but there is still another requirement.

If the user selects request_exception, they should not be able to submit the Record Producer without adding an attachment.

This validation is handled separately in an onSubmit Catalog Client Script.

The important point here is that we do not make attachments globally mandatory.

Instead, we perform the validation only when:

 
question_tipo_solicitacao = request_exception
 

This allows the same Record Producer to support both scenarios.

When documentation is required

 

 
request_exception
        ↓
Show attachment button
        ↓
Validate attachment
        ↓
Allow submission only when an attachment exists
 

When documentation is not required

 

 
Any other option
        ↓
Hide attachment button
        ↓
Skip attachment validation
        ↓
Allow submission
 

The complete onSubmit implementation is included in the Complete Solution Overview below.


Why Not Use mandatory_attachment?

This was one of the first options I considered.

The problem is that the business requirement is conditional.

Making attachments mandatory at the Record Producer level effectively gives us:

 
Every request
     ↓
Attachment required
 

But what we actually need is:

 
Specific selection
     ↓
Attachment required
Therefore, the mandatory behavior needs to be evaluated dynamically.

Why Not Disable Attachments?

Another important distinction is between disabling attachments and hiding the attachment button.

If the attachment functionality itself is disabled, the standard component is no longer available for the user when the condition changes.

Instead, the solution keeps attachment functionality available and simply changes the visibility of the UI component.

 

Conceptually:

 

 
Attachment functionality
        │
        ├── remains enabled
        │
        └── button visibility
                │
                ├── request_exception → visible
                └── other values      → hidden
 

This gives us much more flexibility.


Why Keep the Standard ServiceNow Attachment Component?

Another option would be to create a completely custom attachment component.

For this requirement, I didn't want to do that.

A custom attachment implementation could introduce additional complexity around:

  • file uploads;
  • attachment deletion;
  • security;
  • accessibility;
  • portal behavior;
  • mobile responsiveness;
  • future maintenance.

ServiceNow already provides all of that functionality.

The only behavior we needed to customize was when the user should see and be required to use it.

So instead of replacing the standard component, the final approach was:

 

 
Native ServiceNow attachment component
                 +
          Catalog Client Scripts
                 ↓
       Conditional behavior
 

This kept the customization relatively small.


Important Consideration: DOM Manipulation

There is an important consideration with this solution.

This line:

 

 
this.document.querySelector('sp-attachment-button');
 

interacts directly with the DOM rendered by ServiceNow.

The sp-attachment-button element is part of the portal UI implementation and is not the same as using a documented GlideForm method such as:

 

 
g_form.getValue();
 

Therefore, this solution has an upgrade consideration.

If ServiceNow changes how the attachment component is rendered in a future release, the selector may need to be updated.

For that reason, I recommend:

  • documenting this customization;
  • regression-testing it after platform upgrades;
  • testing it when changing portal experiences;
  • avoiding the assumption that the same implementation will work in Workspace.

Employee Center vs. Workspace

This implementation was designed and tested for an Employee Center / Service Portal-based experience.

It should not automatically be assumed to work in a Configurable Workspace.

Workspace uses a different UI architecture, and DOM-based customizations created for Service Portal or Employee Center may not apply there.

If the same requirement needs to be implemented in Workspace in the future, I would recommend evaluating the Workspace-specific extension points instead of simply copying the DOM manipulation.


Complete Solution Overview

The final implementation consists of three Catalog Client Scripts.

 

Catalog Client Script — onLoad

This script determines whether the attachment button should be visible when the Record Producer initially loads.

 

 
function onLoad() {
    var value =
        g_form.getValue('question_tipo_solicitacao');

    toggleAttachmentButton(
        value === 'request_exception'    );
}

function toggleAttachmentButton(show) {
    var attachmentButton =
        this.document.querySelector('sp-attachment-button');

    if (!attachmentButton) {
        return;
    }

    attachmentButton.style.display = show ? '' : 'none';
}

 

Catalog Client Script — onChange

This script updates the attachment button whenever the user changes the controlling variable.

 

 
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading) {
        return;
    }

    toggleAttachmentButton(
        newValue === 'request_exception'    );
}

function toggleAttachmentButton(show) {
    var attachmentButton =
        this.document.querySelector('sp-attachment-button');

    if (!attachmentButton) {
        return;
    }

    attachmentButton.style.display = show ? '' : 'none';
}

Catalog Client Script — onSubmit

The final step is validating whether an attachment exists when the selected option requires one.

In this scenario, the validation needed to work both in the Portal/Employee Center and in the Native UI.

 

 
function onSubmit() {
    var typeRequest =
        g_form.getValue('question_tipo_solicitacao');

    if (window == null) {
        // Portal / Employee Center
        var count =
            this.document
                .getElementsByClassName('get-attachment')
                .length;

        if (
            count == 0 &&
            typeRequest == 'request_exception'        ) {
            g_form.addErrorMessage(
                'Anexo obrigatório para motivo médico ou indicação médica.'            );

            return false;
        }

    } else {
        // Native UI
        var length =
            $j('li.attachment_list_items')
                .find('span')
                .length;

        if (
            length == 0 &&
            typeRequest == 'request_exception'        ) {
            g_form.addErrorMessage(
                'Anexo obrigatório para motivo médico ou indicação médica.'            );

            return false;
        }
    }

    return true;
}
 

How it works

The script first checks the value of:

 

 
question_tipo_solicitacao
 

If the selected value is:

 

 
request_exception
then at least one attachment is required.

For the Portal / Employee Center, the script checks the number of elements with:

 

 
getElementsByClassName('get-attachment')
 

For the Native UI, the script checks:

 

 
$j('li.attachment_list_items')
 

If no attachment is found, the submission is blocked and an error message is displayed.

The final validation logic is:

 

 
request_exception selected
        +
no attachment found
        ↓
block submit
 

Otherwise, the form can be submitted normally.

Important: This validation also relies on UI/DOM elements rendered by ServiceNow. Because of that, it should be regression-tested after upgrades, especially if the portal or native attachment markup changes.


Final Result

With this approach, the Record Producer keeps the native ServiceNow attachment functionality while providing conditional behavior based on the user's selection.

The complete flow becomes:

 

 
                                    Record Producer
                                                  │
                                                 ▼
                               Check controlling variable
                                                  │
              ┌───────────┴───────────┐
              │                                                                      │
     request_exception                                  Other value
              │                                                                     │
              ▼                                                                    ▼
      Show attachment button              Hide attachment button
              │                                                                     │
              ▼                                                                    │
      Require attachment                                           │
              │                                                                     │
              └───────────┬───────────┘
                                                 ▼
                                            Submit
 

No custom upload component is required, and the user continues interacting with the standard ServiceNow attachment experience.


Conclusion

What initially looked like a simple requirement ended up requiring a little more investigation than expected.

I found several discussions about attachments while researching this topic, but I couldn't find one complete example covering the combination of:

dynamic visibility + conditional mandatory behavior + the native attachment component.

The key was realizing that these are separate concerns:

  1. Keep the native attachment functionality enabled.
  2. Control the visibility of the standard attachment button.
  3. Validate the business requirement separately during submission.

This approach allowed me to meet the requirement without replacing ServiceNow's attachment functionality with a custom component.

Since I spent quite some time searching for this specific scenario, I wanted to document the complete approach in one place.

Hopefully, this helps someone facing the same requirement — and saves a little bit of investigation time. 🙂

0 REPLIES 0