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.
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; returningfalseblocks the submit.
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);
}
}
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:
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
Make Configuration Item required for Hardware incidents
Solve the same requirement two ways to feel the tradeoff directly.
Requirements:
- Build a UI Policy on
incident: when Category = Hardware, make Configuration Item mandatory and visible. - Now disable that UI Policy, and reimplement the same behavior as an
onChangeClient Script on the Category field usingg_form.setMandatory(). - Add a check: if the user picks Hardware but Configuration Item is still empty on submit, block the submit with
g_form.showFieldMsg()in anonSubmitscript. - Re-enable the UI Policy and disable your Client Script — confirm both approaches produce the same visible behavior.
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?
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?
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?
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?
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.