Restriction validation on Record Producer variable

JP-ODU
Tera Guru

Problem: users are copy+pasting outlook sent to lists (separated by semicolons) into our watch list field on record producers, but ServiceNow needs commas, not semicolons, to interpret email addresses, correctly.

 

Solution(?): onChange script to disallow characters other than @, ., and , and throw an error message to the user so they know to adjust their input.

 

Issue: the script I'm trying has some flaw I'm not seeing. It reliably scrubs entries with disallowed characters, but I'm not seeing an error message displayed for the user entering it?

 

Script:

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

    var emailNamePattern = /^[^_\s][^\/:\~\&\%\;\^\{\}\[\]\<\>\|\#\$\*\?\'\"\+\=]{1,63}[^\.]$/;
    if (!emailNamePattern.test(newValue)) {
        g_form.showFieldMsg('watch_list', 'Emails may only contain @ and . characters. Please separate emails using commas (,) and not semicolons (;).', 'error');
        g_form.setValue('watch_list', oldValue); 
    } else {
        g_form.hideFieldMsg('watch_list');
    }
}

Could someone please correct me? What am I doing wrong? Thanks!

1 ACCEPTED SOLUTION

Ankur Bawiskar
Tera Patron

@JP-ODU 

try this

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || !newValue || newValue === oldValue) return;
    
    // Only fix if semicolons exist (prevents loop)
    if (newValue.indexOf(';') !== -1) {
        var fixedValue = newValue.replace(/;/g, ',');
        g_form.setValue('watch_list', fixedValue);
        g_form.addInfoMessage('Semicolons auto-changed to commas');
    }
}

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

View solution in original post

3 REPLIES 3

Ankur Bawiskar
Tera Patron

@JP-ODU 

try this

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || !newValue || newValue === oldValue) return;
    
    // Only fix if semicolons exist (prevents loop)
    if (newValue.indexOf(';') !== -1) {
        var fixedValue = newValue.replace(/;/g, ',');
        g_form.setValue('watch_list', fixedValue);
        g_form.addInfoMessage('Semicolons auto-changed to commas');
    }
}

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Perfect. Thank you very much!

KingC
Kilo Contributor

Your Question:

"Problem: users are copy+pasting outlook sent to lists (separated by semicolons) ..."

AI Response: by Claude Opus 4.5

/* SOLUTION 1: CONFIGURATION-ONLY */

Not achievable through configuration alone. ServiceNow does not provide out-of-box configuration options to automatically convert semicolons to commas in watch list fields or to validate email separator characters without scripting.

/* ============================================== */

/* SOLUTION 2: HYBRID SOLUTION */

/*
CONFIGURATION STEP:

Navigate to the Record Producer in question
Locate the watch_list variable
Add a Help Text or Instructions field with guidance:
"Enter email addresses separated by commas (,). Do not use semicolons (;)."

SCRIPT STEP:
Create a Catalog Client Script attached to the Record Producer
*/

/*
Script Name: Validate Watch List Email Format
Type: Catalog Client Script
Applies to: [Your Record Producer Name]
UI Type: Both (Desktop and Mobile)
Type: onChange
Variable name: watch_list
Active: true
*/

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

// Check if semicolons are present - this is the most common copy/paste issue
if (newValue.indexOf(';') !== -1) {
// Auto-convert semicolons to commas for better user experience
var correctedValue = newValue.replace(/;/g, ',');
g_form.setValue('watch_list', correctedValue);
g_form.showFieldMsg('watch_list', 'Semicolons have been automatically converted to commas.', 'info');
return;
}

g_form.hideFieldMsg('watch_list');

}

/* ============================================== */

/* SOLUTION 3: SCRIPTING-ONLY */

/*
This solution addresses the original issue: the regex pattern was too complex and
was likely rejecting valid email addresses, causing the field to reset but the
message timing was problematic.

The issue with the original script:

The regex was designed to match email NAME patterns, not full email addresses
The pattern rejected many valid characters that appear in email addresses
showFieldMsg was being called but may have been immediately hidden due to
setValue triggering another onChange event

Script Name: Watch List Email Separator Validation
Type: Catalog Client Script
Applies to: [Your Record Producer Name]
UI Type: Both
Type: onChange
Variable name: watch_list
Active: true
*/

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue === '') {
g_form.hideFieldMsg('watch_list');
return;
}

// Define disallowed characters - semicolon is the primary offender from Outlook
var disallowedChars = /[;\^\{\}\[\]\<\>\|\#\$\*\?\'\"\+\=\~\&\%]/;

if (disallowedChars.test(newValue)) {
// Check specifically for semicolons to give targeted guidance
if (newValue.indexOf(';') !== -1) {
g_form.showFieldMsg('watch_list', 'Please separate email addresses using commas (,) instead of semicolons (;). Outlook uses semicolons, but ServiceNow requires commas.', 'error');
} else {
g_form.showFieldMsg('watch_list', 'The watch list contains invalid characters. Please enter valid email addresses separated by commas.', 'error');
}

// Use setTimeout to prevent the message from being cleared by the subsequent onChange
// that fires when setValue is called
var previousValue = oldValue;
setTimeout(function() {
g_form.setValue('watch_list', previousValue);
}, 100);

} else {
g_form.hideFieldMsg('watch_list');
}

}

/*
ALTERNATIVE SOLUTION 3B - AUTO-CORRECT APPROACH (BETTER USER EXPERIENCE)
This version automatically fixes the input rather than rejecting it

Script Name: Watch List Auto-Correct Semicolons
Type: Catalog Client Script
Applies to: [Your Record Producer Name]
UI Type: Both
Type: onChange
Variable name: watch_list
Active: true
*/

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

var originalValue = newValue;
var correctedValue = newValue;
var corrections = [];

// Replace semicolons with commas (Outlook copy/paste fix)
if (correctedValue.indexOf(';') !== -1) {
correctedValue = correctedValue.replace(/;/g, ',');
corrections.push('semicolons converted to commas');
}

// Remove extra spaces around commas
correctedValue = correctedValue.replace(/\s*,\s*/g, ',');

// Remove duplicate commas
correctedValue = correctedValue.replace(/,+/g, ',');

// Remove leading/trailing commas
correctedValue = correctedValue.replace(/^,|,$/g, '');

// Only update if changes were made
if (originalValue !== correctedValue) {
g_form.setValue('watch_list', correctedValue);

if (corrections.length > 0) {
g_form.showFieldMsg('watch_list', 'Auto-corrected: ' + corrections.join(', ') + '. Please verify the email list is correct.', 'info');

// Clear the info message after 5 seconds
setTimeout(function() {
g_form.hideFieldMsg('watch_list');
}, 5000);
}
} else {
g_form.hideFieldMsg('watch_list');
}

}

/* ============================================== */

/* SELF-CRITIQUE */

/*
ADHERENCE TO REQUIREMENTS:

Solution 2 and 3 both address the core problem of Outlook semicolon separators
The original script issue is explained: the regex was overly complex and the
setValue was triggering another onChange which may have hidden the message immediately

CLARITY & EFFICIENCY:

Solution 3B (auto-correct) provides the best user experience by fixing the problem
automatically rather than requiring user action
The strict validation approach (Solution 3) preserves the original intent but
uses setTimeout to ensure the message displays before the field resets

POTENTIAL FLAWS:

setTimeout introduces a slight race condition - in slow browsers the timing may vary
The auto-correct approach may make unexpected changes if users intentionally
included unusual characters
Watch list fields with sys_ids (from reference pickers) would not be affected
since those are already properly formatted

SUGGESTIONS FOR IMPROVEMENT:

Consider using onSubmit validation as a backup to catch any edge cases
For the strict validation approach, consider using g_form.clearValue() instead
of setValue(oldValue) to avoid the onChange re-trigger issue entirely
Add server-side validation via a Catalog Script that runs before insert to
ensure data integrity regardless of client-side bypass
Consider adding a user preference to enable/disable auto-correction
*/