ServiceNow fires onChange events during form load as each field gets populated, not just on user interaction. Without proper guards, your logic executes dozens of times before the user even sees the form. The isLoading parameter is your lifeline — it stays true until all fields finish loading. Most developers forget the oldValue == newValue check, causing logic to run even when calculated fields refresh with the same value.

When to use this pattern

  • When you need to enforce business rules based on field changes (mandatory fields, visibility, calculations)
  • When making GlideAjax calls that should only fire on actual user changes, not form load
  • When populating dependent fields or clearing related data based on user selections
  • When showing contextual field messages or alerts that should only appear after user interaction

When NOT to use this pattern

  • Don't use for one-time form initialization logic — use an onLoad Client Script instead
  • Don't use for expensive operations on every keystroke — debounce with setTimeout() or use onSubmit
  • Don't use when you need server-side field access — put the logic in a Business Rule instead
  • Don't use for complex validation — use Data Policies or server-side validation in Business Rules

Key behaviors and gotchas

  • Use == not === for value comparison — ServiceNow sometimes passes empty strings vs null inconsistently
  • The isTemplate parameter is true when loading records from templates — skip this to avoid premature logic execution
  • Reference fields pass display values in oldValue and newValue — use g_form.getValue() for sys_ids
  • Choice fields fire onChange even when users select the same option — the value comparison catches this
  • Calculated fields and UI Policies can trigger onChange events when they refresh — guard against this with value comparison
  • Mobile apps may fire onChange events differently — always test on mobile if your users access forms there
⚠️

Never call g_form.setValue() inside onChange for the same field — you'll create an infinite loop. Use a flag variable or move the logic to a different event if you need to modify the field that triggered the change.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime