What it does
JavaScript held in Script web resources, attached to events on model-driven forms and grids, running against the Client API object model. It's the long-standing way to make a form react to what the user does before anything reaches the server.
Key facts
- Scripts attach to form OnLoad, form data OnLoad, form Loaded, form OnSave, column OnChange, lookup PreSearch, and several knowledge-base search events. Some can be wired up in the form designer's Events tab; the rest have to be attached in code with
addOnChange,addOnLoad,addOnSaveand friends. - Microsoft's own guidance is to try business rules first. Client scripting is the escalation, not the default.
- The execution context is passed automatically as the first parameter to handlers registered in code. From it you get the form context via
getFormContext. - Event handlers aren't called when a form is in bulk edit mode by default. To change that you edit the Form XML and set
BehaviorInBulkEditFormtoEnabledon the event element — and currently that's only supported for OnLoad. - Some Client APIs are deprecated in the current release, and Microsoft maintains a published list of them.
- The same Client API concepts and methods apply to Dynamics 365 Customer Engagement (on-premises).
- Scripts are solution components because they're web resources, so they move between environments with everything else.
When to use / skip
Use it when the behaviour is genuinely conditional on what's on the form right now — cascading lookup filters, dynamic requirement levels, cancelling a save with a real explanation, calling the Web API to check something before the user commits. Skip it when a business rule, a calculated column, a rollup or a plugin does the same job, and skip it particularly when the logic must always hold. Client script runs in the browser and can be bypassed; anything that's a real rule belongs server-side in a plugin. The usual failure is a client with fifteen years of accumulated form scripts that nobody dares touch, none of which are enforced anywhere else.
Configuration decisions
- Business rule, client script, or plugin — decided by whether the logic is cosmetic, conditional, or contractual.
- Whether handlers are registered in the form designer or in code, since the second gives you the execution context automatically and keeps registration versioned with the script.
- How scripts are organised into web resources: one library per table is the usual convention, and it's better than one enormous shared file.
- Whether bulk edit needs to respect your OnLoad logic, which means Form XML editing.
- How you handle async work in OnLoad, given that the form renders regardless of what your promises are doing.
Gotchas
- Client script isn't a security control. Hiding a field, locking a control or blocking a save stops the UI, not the API, and not a Power Automate flow.
- Deprecated APIs keep working until they don't.
Xrm.Pagepatterns in inherited code are a maintenance debt with a clock on them. - Bulk edit silently skips your handlers. Validation that only exists in an OnChange handler doesn't run when a user updates fifty records at once.
- Scripts run on every form load including quick create and mobile, unless you check the form type. A lot of "the app is slow on tablets" traces back to this.
- Errors in one handler can stop later handlers from running. A missing null check in an old script breaks the new one.
Consultant notes
- When you inherit an environment, inventory the script web resources before you promise anything about the forms. The answer is usually worse than the client thinks.
- Push hard on the business rule versus script boundary during design. Every script is a permanent dependency on someone who can read JavaScript, and the client rarely has one.
- Where the logic protects data, insist it also exists server-side. "The form stops them" is not a control anyone should sign off.
- PCF components and custom pages are Microsoft's steer for anything visual or reusable. Scripts still win for cross-field form behaviour, and they're not going anywhere — say so plainly rather than letting a client assume scripting is deprecated.
Check the deprecated Client API list at each release wave, and again before quoting any script remediation work.