How to auto-expand CC and BCC fields by default?

srohan24
Tera Contributor

I have a requirement to auto-expand the CC and BCC fields by default when users open the Email (Compose Email) from a form (e.g., Case/Incident) in ServiceNow.

  • Current Behavior
    • When users click on Email / Compose, the email client opens
    • The CC and BCC fields are collapsed by default
    • Users need to manually click on “CC” and “BCC” to expand them
  • Requirement
    • CC and BCC fields should be visible (expanded) by default when the email client loads
    • This should apply for all users across the platform

Refer the attached screenshots. Image 2 is current behavior, Image 3 is requirement.

1 REPLY 1

Naveen20
ServiceNow Employee

The CC and BCC fields in the Compose Email dialog are collapsed by default and toggled via client-side JavaScript. The most reliable and upgrade-safe approach is a Global UI Script that detects when the email compose dialog opens and programmatically expands those fields.

 

Try this
System UI > UI Scripts and create a new record:

Field Value
Name Auto Expand CC BCC 
Global true
Active true

Script:

 
/*
 * Auto-expand CC and BCC fields in Compose Email dialog.
 * Uses MutationObserver to detect when the email dialog is injected into the DOM,
 * then triggers the CC/BCC toggle so fields are visible by default.
 */
(function() {
    'use strict';

    function expandCcBcc(dialogEl) {
        // Look for the CC/Bcc toggle links/buttons inside the email compose dialog
        // In the standard email client the collapsed state shows "Cc" and "Bcc" as
        // clickable links in the To row. Clicking them reveals the full input fields.
        var toggles = dialogEl.querySelectorAll(
            '.email-cc-bcc-toggle, a[data-action="show-cc"], a[data-action="show-bcc"], ' +
            '.cc-bcc-link, .toggle-cc, .toggle-bcc'
        );

        // Fallback: find any anchor/span whose text is exactly "Cc" or "Bcc"
        if (!toggles || toggles.length === 0) {
            var allLinks = dialogEl.querySelectorAll('a, span.btn, button');
            toggles = [];
            for (var i = 0; i < allLinks.length; i++) {
                var txt = (allLinks[i].textContent || '').trim();
                if (txt === 'Cc' || txt === 'Bcc') {
                    toggles.push(allLinks[i]);
                }
            }
        }

        for (var j = 0; j < toggles.length; j++) {
            toggles[j].click();
        }
    }

    // Observe the DOM for the email compose dialog appearing
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            for (var k = 0; k < mutation.addedNodes.length; k++) {
                var node = mutation.addedNodes[k];
                if (node.nodeType !== 1) continue; // element nodes only

                // Check if this node IS or CONTAINS the email compose dialog
                var dialog = null;
                if (node.classList && (
                    node.classList.contains('email-compose') ||
                    node.classList.contains('email_client') ||
                    node.id === 'email_client_iframe'
                )) {
                    dialog = node;
                } else if (node.querySelector) {
                    dialog = node.querySelector(
                        '.email-compose, .email_client, #email_client_iframe'
                    );
                }

                if (dialog) {
                    // Small delay to let the dialog fully render its internal fields
                    setTimeout(function() {
                        expandCcBcc(dialog);
                    }, 500);
                }

                // Handle iframe-based email client (classic UI)
                if (node.tagName === 'IFRAME' || (node.querySelector && node.querySelector('iframe'))) {
                    var iframe = (node.tagName === 'IFRAME') ? node : node.querySelector('iframe');
                    if (iframe) {
                        iframe.addEventListener('load', function() {
                            try {
                                var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                                setTimeout(function() {
                                    expandCcBcc(iframeDoc);
                                }, 500);
                            } catch (e) {
                                // Cross-origin restrictions – skip
                            }
                        });
                    }
                }
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });
})();