Week 3: Forms, Lists, UI Policies & Client Scripts

This is the browser-side layer — the closest thing ServiceNow has to component-level logic, and the layer where your instinct to reach for JavaScript event handlers will serve you well. The trick is knowing when a declarative UI Policy beats a Client Script, since both can solve the same problem with very different maintainability.

Module 3 of 25 Week 3 of 26 ~3–4 Hours Hands-on Exercise Included

By the end of this week, you'll be able to

  • Configure form sections and list layouts without touching a script
  • Build a UI Policy that shows, hides or requires fields based on conditions
  • Write onLoad/onChange/onSubmit Client Scripts using the g_form API

1. Form & List Layout

Forms are generated from a table's dictionary, but their arrangement — sections, field order, related lists shown — is configured separately via "Configure > Form Layout" (drag fields between "Available" and the form's sections) and "Configure > List Layout" for the equivalent on list views. None of this requires a script; it's the first line of customization to reach for before writing any code.

2. UI Policies: Declarative Field Behavior

A UI Policy is a condition (built with the same condition builder used in list filters) plus a set of declarative actions — make a field mandatory, visible, or read-only — that the platform applies automatically, with no script required for the common cases.

UI Policy — conceptual example
Table: incident
Condition: Category is "Hardware"
Actions:
  - Configuration Item -> Mandatory: true
  - Short Description -> Visible: true

UI Policies also have an optional "UI Policy Script" for logic the declarative actions can't express — but reach for that only after confirming the pure declarative form doesn't cover your case, since it stays readable to the next admin without opening a script editor.

3. Client Scripts: onLoad, onChange, onSubmit

When a UI Policy's declarative model isn't enough — anything involving a GlideAjax call, custom validation logic, or a message box — a Client Script is plain JavaScript that runs in the browser, triggered by one of three events:

  • onLoad — fires once when the form finishes loading.
  • onChange — fires when a specific field's value changes.
  • onSubmit — fires on form submission; returning false blocks the submit.
onChange Client Script — incident.category
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
  if (isLoading || newValue === '') return;

  if (newValue === 'hardware') {
    g_form.setMandatory('cmdb_ci', true);
  } else {
    g_form.setMandatory('cmdb_ci', false);
  }
}
Guard the isLoading flag

Every onChange script fires once during the form's initial load too. Skipping logic while isLoading is true (as above) is the standard guard against running side effects — like popping an alert — before the user has actually interacted with anything.

4. The g_form API

g_form is the client-side handle to the form you're scripting against — read values, set values, toggle field states, and show messages, all without touching the DOM directly:

common g_form calls
g_form.getValue('priority');           // read
g_form.setValue('priority', '1');       // write
g_form.setMandatory('short_description', true);
g_form.setVisible('resolution_notes', false);
g_form.setReadOnly('caller_id', true);
g_form.addInfoMessage('Saved successfully.');
g_form.showFieldMsg('short_description', 'Required for P1 incidents', 'error');

If you've used a form library that hands you an imperative escape hatch alongside declarative bindings, this will feel familiar: UI Policies are the declarative layer, g_form in a Client Script is the imperative escape hatch for everything they can't express.

5. Hands-on Exercise

Hands-on

Make Configuration Item required for Hardware incidents

Solve the same requirement two ways to feel the tradeoff directly.

Requirements:

  1. Build a UI Policy on incident: when Category = Hardware, make Configuration Item mandatory and visible.
  2. Now disable that UI Policy, and reimplement the same behavior as an onChange Client Script on the Category field using g_form.setMandatory().
  3. Add a check: if the user picks Hardware but Configuration Item is still empty on submit, block the submit with g_form.showFieldMsg() in an onSubmit script.
  4. Re-enable the UI Policy and disable your Client Script — confirm both approaches produce the same visible behavior.
Hint

onSubmit scripts must return false explicitly to block submission — returning nothing (undefined) is treated as "allow the submit," a common source of a validation script that silently does nothing.

6. Knowledge Check

Four quick questions. Expand each to check your answer.

Q1

When should you reach for a UI Policy instead of a Client Script?

Whenever the requirement is expressible as "if this condition, then make this field mandatory/visible/read-only" — the common cases UI Policies cover declaratively without a script editor. Client Scripts are for logic UI Policies can't express: custom validation, server calls, or anything beyond simple field-state toggles.

Q2

Why do onChange Client Scripts typically check the isLoading parameter?

An onChange handler also fires once during the form's initial load, not just on user-driven changes. Guarding with `if (isLoading) return;` prevents side effects meant for actual user interaction — like popups or forced value changes — from firing before the user has touched anything.

Q3

What happens if an onSubmit Client Script doesn't explicitly return false?

The submission proceeds. onSubmit scripts must return false explicitly to block the form from saving — returning nothing (undefined) is treated the same as "allow the submit," which is a common cause of a validation script that appears to do nothing.

Q4

What is g_form, and how does it relate to UI Policies?

g_form is the client-side JavaScript API for reading and writing form state — values, visibility, mandatory status, messages — inside a Client Script. It's the imperative counterpart to UI Policies' declarative conditions-and-actions model, used when you need logic UI Policies can't express.