client-scripts

Client Script Patterns for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "client-scripts" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-client-scripts

Client Script Patterns for ServiceNow

Client Scripts run in the user's browser and control form behavior. Unlike server-side scripts, client scripts can use modern JavaScript (ES6+) in modern browsers.

Client Script Types

Type When it Runs Use Case

onLoad Form loads Set defaults, hide/show fields, initial setup

onChange Field value changes React to user input, cascading updates

onSubmit Form submitted Validation before save

onCellEdit List cell edited Validate inline edits

The g_form API

Getting and Setting Values

// Get field value var priority = g_form.getValue("priority") var callerName = g_form.getDisplayValue("caller_id") // Reference display value

// Set field value g_form.setValue("priority", "1") g_form.setValue("assigned_to", userSysId, "John Smith") // Reference with display

// Clear a field g_form.clearValue("assignment_group")

Field Visibility and State

// Show/Hide fields g_form.setVisible("u_internal_notes", false) g_form.setDisplay("u_internal_notes", false) // Removes from DOM

// Make field mandatory g_form.setMandatory("short_description", true)

// Make field read-only g_form.setReadOnly("caller_id", true)

// Disable field (grayed out but visible) g_form.setDisabled("state", true)

Messages and Validation

// Field-level messages g_form.showFieldMsg("email", "Invalid email format", "error") g_form.hideFieldMsg("email")

// Form-level messages g_form.addInfoMessage("Record saved successfully") g_form.addErrorMessage("Please fix the errors below") g_form.clearMessages()

// Flash a field to draw attention g_form.flash("priority", "#ff0000", 0) // Red flash

Sections and Labels

// Collapse/Expand sections g_form.setSectionDisplay("notes", false) // Collapse g_form.setSectionDisplay("notes", true) // Expand

// Change field label g_form.setLabelOf("short_description", "Issue Summary")

Common Patterns

Pattern 1: onLoad - Set Defaults

function onLoad() { // Only on new records if (g_form.isNewRecord()) { // Set default priority g_form.setValue("priority", "3")

// Set caller to current user
g_form.setValue("caller_id", g_user.userID)

// Hide internal fields from end users
if (!g_user.hasRole("itil")) {
  g_form.setVisible("assignment_group", false)
  g_form.setVisible("assigned_to", false)
}

} }

Pattern 2: onChange - Cascading Updates

function onChange(control, oldValue, newValue, isLoading) { // Don't run during form load if (isLoading) return

// When category changes, clear subcategory if (newValue != oldValue) { g_form.setValue("subcategory", "") g_form.clearValue("u_item") }

// Auto-set priority based on category if (newValue == "security") { g_form.setValue("priority", "1") g_form.setReadOnly("priority", true) } else { g_form.setReadOnly("priority", false) } }

Pattern 3: onChange with GlideAjax

function onChange(control, oldValue, newValue, isLoading) { if (isLoading || newValue == "") return

// Get data from server var ga = new GlideAjax("MyScriptInclude") ga.addParam("sysparm_name", "getUserDetails") ga.addParam("sysparm_user_id", newValue) ga.getXMLAnswer(function (response) { var data = JSON.parse(response)

// Update form with server data
g_form.setValue("location", data.location)
g_form.setValue("department", data.department)
g_form.setValue("u_vip", data.vip)

if (data.vip == "true") {
  g_form.setValue("priority", "1")
  g_form.flash("priority", "#ffff00", 2)
}

}) }

Pattern 4: onSubmit - Validation

function onSubmit() { // Validate email format var email = g_form.getValue("u_email") if (email && !isValidEmail(email)) { g_form.showFieldMsg("u_email", "Please enter a valid email", "error") return false // Prevent submit }

// Require close notes when resolving var state = g_form.getValue("state") var closeNotes = g_form.getValue("close_notes") if (state == "6" && !closeNotes) { g_form.showFieldMsg("close_notes", "Close notes required", "error") g_form.setMandatory("close_notes", true) return false }

// Confirm before high-priority submission var priority = g_form.getValue("priority") if (priority == "1") { return confirm("This will create a Priority 1 incident. Continue?") }

return true // Allow submit }

function isValidEmail(email) { var regex = /^[^\s@]+@[^\s@]+.[^\s@]+$/ return regex.test(email) }

Pattern 5: Conditional Mandatory Fields

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

// Category "Hardware" requires asset tag var isHardware = newValue == "hardware" g_form.setMandatory("u_asset_tag", isHardware) g_form.setDisplay("u_asset_tag", isHardware)

// Category "Software" requires application name var isSoftware = newValue == "software" g_form.setMandatory("u_application", isSoftware) g_form.setDisplay("u_application", isSoftware) }

GlideAjax Pattern (Server Communication)

Client Script

function onChange(control, oldValue, newValue, isLoading) { if (isLoading || !newValue) return

var ga = new GlideAjax("IncidentUtils") ga.addParam("sysparm_name", "getRelatedIncidents") ga.addParam("sysparm_ci", newValue) ga.getXMLAnswer(handleResponse) }

function handleResponse(response) { var result = JSON.parse(response)

if (result.count > 0) { g_form.addWarningMessage("There are " + result.count + " related open incidents for this CI") } }

Server Script Include

var IncidentUtils = Class.create() IncidentUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, { getRelatedIncidents: function () { var ci = this.getParameter("sysparm_ci") var result = { count: 0, incidents: [] }

var gr = new GlideRecord("incident")
gr.addQuery("cmdb_ci", ci)
gr.addQuery("active", true)
gr.query()

result.count = gr.getRowCount()
while (gr.next()) {
  result.incidents.push({
    number: gr.getValue("number"),
    short_description: gr.getValue("short_description"),
  })
}

return JSON.stringify(result)

},

type: "IncidentUtils", })

g_user Object

// Current user information var userName = g_user.userName // User name var userID = g_user.userID // sys_id var firstName = g_user.firstName // First name var lastName = g_user.lastName // Last name var fullName = g_user.getFullName() // Full name

// Role checks if (g_user.hasRole("admin")) { } if (g_user.hasRole("itil")) { } if (g_user.hasRoleExactly("incident_manager")) { } // Exact match, no admin override

// Multiple roles if (g_user.hasRoleFromList("itil,incident_manager")) { }

Performance Best Practices

  1. Minimize Server Calls

// ❌ BAD - Multiple GlideAjax calls onChange: getUserLocation() onChange: getUserDepartment() onChange: getUserManager()

// ✅ GOOD - Single call returning all data onChange: getUserDetails() // Returns location, department, manager

  1. Use isLoading Parameter

function onChange(control, oldValue, newValue, isLoading) { // ❌ BAD - Runs during form load callServer(newValue)

// ✅ GOOD - Skip during load if (isLoading) return callServer(newValue) }

  1. Debounce Rapid Changes

var timeout function onChange(control, oldValue, newValue, isLoading) { if (isLoading) return

clearTimeout(timeout) timeout = setTimeout(function () { performExpensiveOperation(newValue) }, 300) // Wait 300ms for typing to stop }

Common Mistakes

Mistake Problem Solution

Forgetting isLoading check Script runs unnecessarily on load Always check if (isLoading) return;

Blocking onSubmit UI freezes on slow validation Use async validation with callback

No error handling in GlideAjax Silent failures Add error callbacks

Testing only in one browser Cross-browser issues Test Chrome, Firefox, Edge

Direct DOM manipulation Breaks with UI updates Use g_form API

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

mobile-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

code-review

No summary provided by upstream source.

Repository SourceNeeds Review
General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review