crmForm to Xrm.Page to formContext: form scripting from CRM 3.0 to Dataverse
Four generations of form script. Code pasted into events against crmForm in CRM 3.0 and 4.0, Xrm.Page and JScript web resources in 2011, crmForm removed in 2013, and formContext today. What changed, what broke, and the same tasks written each way.
Answer first
Form scripting has had four shapes:
| Era | You script against | Where the code lives |
|---|---|---|
| CRM 3.0 and 4.0 | crmForm, plus 4.0’s global functions and variables |
Pasted into each form or field event in the form editor |
| CRM 2011 | Xrm.Page; crmForm deprecated but still working |
JScript web resource libraries, with named functions registered as event handlers |
| CRM 2013 to 9.x | Xrm.Page; the 4.0 object model removed |
JScript web resources |
| Dataverse and 9.x | formContext, from executionContext.getFormContext(); Xrm.Page deprecated but supported |
JScript web resources |
The recurring lesson is supportability. Every version told developers to
use only documented objects. Every upgrade broke scripts that didn’t: the
2011 update that added browsers other than Internet Explorer, the 2013 removal
of the 4.0 object model, and now the Xrm.Page deprecation.
Each section names its sources: the CRM 3.0, 4.0 and 2011 SDKs and product Help, Microsoft’s archived CRM 2013 documentation, and current documentation.
The same tasks, era by era
Sources: each cell comes from that era’s own Microsoft documentation. A dash means this site hasn’t sourced it. Microsoft never published a crmForm-to-Xrm.Page mapping, so read across a row as “how each era did this job”, not as an official conversion table.
| Task | CRM 3.0 and 4.0 | CRM 2011 to 2013 | Dataverse and 9.x |
|---|---|---|---|
| Read a field | crmForm.all.jobtitle.DataValue |
Xrm.Page.getAttribute("firstname").getValue() |
formContext.getAttribute("firstname").getValue() |
| Create or update form? | crmForm.FormType (1 create, 2 update) |
Xrm.Page.ui.getFormType() |
— |
| Cancel a save | event.returnValue = false in OnSave |
— | — |
| Server or client URL | 4.0: the SERVER_URL global |
Xrm.Page.context.getServerUrl(), later deprecated for getClientUrl() |
The global context, from Xrm.Utility.getGlobalContext() |
| Organization name | 4.0: ORG_UNIQUE_NAME |
Xrm.Page.context.getOrgUniqueName() |
globalContext.organizationSettings.uniqueName |
| User’s language | 4.0: USER_LANGUAGE_CODE |
Xrm.Page.context.getUserLcid() |
globalContext.userSettings.languageId |
| Running in Outlook? | 4.0: IsOutlookClient() |
isOutlookClient(); from 2013, client.getClient |
— |
| Online or offline? | 4.0: IsOnline() |
isOutlookOnline(); from 2013, client.getClientState |
— |
| Authenticate a web service call | 4.0: GenerateAuthenticationHeader() for the 2007 SOAP endpoint |
The global function kept for upgraded code; context.getAuthenticationHeader deprecated; REST and SOAP endpoints for web resources |
Xrm.WebApi |
| Reuse code | No supported way; each event held its own script | JScript libraries as web resources, up to 50 handlers per event | JScript web resources, with the execution context passed in |
CRM 3.0 and 4.0: crmForm
Sources: the CRM 3.0 SDK and Help, and the CRM 4.0 SDK and Help.
- Scripts were JScript, typed into the form editor against the form’s OnLoad and OnSave events and each field’s OnChange. They were saved with the entity and travelled with exported customizations. In 4.0 the web application and Outlook ran the same scripts.
- Forms were HTML pages in Internet Explorer. The 4.0 SDK supports only the properties and methods it documents; any other DHTML object is unsupported.
- 3.0 already broke 1.2 scripts. Fields had to be addressed as
crmForm.all.<field>,valuebecameDataValue, and date fields accepted only aDateobject. - OnSave fires even when nothing changed. It can cancel the save with
event.returnValue = false, andevent.Modetells Save (1) from Save and Close (2). - 4.0 added globals:
SERVER_URL,ORG_UNIQUE_NAME,USER_LANGUAGE_CODEandORG_LANGUAGE_CODE, and the functionsIsOnline,IsOutlookClient,IsOutlookLaptopClient,IsOutlookWorkstationClient,PrependOrgNameandGenerateAuthenticationHeader. The last one built the SOAP header for calling the 2007 web services from script. - The 3.0 SDK’s advice was to keep JScript to validation and completing data, put complicated logic in callouts, and never call remote web sites from script.
A 4.0 import trap: importing an entity’s customizations replaces its form scripts, even when the imported customizations have no scripts at all. The 4.0 SDK warns this can silently remove existing scripts.
What 4.0 called unsupported, and later upgrades duly broke:
- editing CRM’s own
.aspx,.jsor.htmfiles; - reusing the JavaScript CRM installs;
- injecting HTML into forms with HTTP modules;
- any API not documented in the SDK.
CRM 2011: Xrm.Page and web resources
Source: the CRM 2011 SDK.
Xrm.Pagearrived with capabilitiescrmFormcouldn’t offer: showing and hiding parts of the form, several controls per attribute, several forms per entity, and navigation items. It splits intocontext,dataandui.crmFormwas deprecated but kept running, for Internet Explorer only. From Update Rollup 12 and the December 2012 Service Update it also needed the system setting “Include HTC support in Microsoft Dynamics CRM forms”. The SDK said support would end in the next major release.- Upgrade converted scripts, it didn’t rewrite them. Each form’s event
scripts became functions in a new JScript library per form, such as
account_main.js, registered as handlers. ThecrmFormcalls inside were left as they were. Watch for doubled handlers: if you later install a solution that handles the same events withXrm.Pagecode, remove the upgraded handlers or both will run. - Libraries and handlers. Code lives in JScript web resources. An event can
have up to 50 handlers, run in the order listed. Ticking “Pass execution
context as first parameter” gives a handler
getEventSource,getDepthandgetSharedVariableandsetSharedVariablefor sharing values between handlers. - Supported replacements for old hacks. The SDK lists methods such as
addCustomViewandsetDefaultViewfor lookups,setLabel,setVisible,setFocus,setRequiredLevel,addOnChangeandaddOnSave. Hiding ribbon buttons moved to ribbon display and enable rules. - Cross-browser support broke unsupported code. The SDK warns that with Update Rollup 12 and the December 2012 Service Update, unsupported scripts were expected to stop working, and points to the Custom Code Validation Tool.
- Old URLs and endpoints kept working for now. 4.0 URLs such as
/SFA/accts/edit.aspxstill worked, butmain.aspx?etn=account&pagetype=entityrecordwas the way forward. 4.0 web service calls kept working through the 2007 endpoint, while the new REST endpoint was easier for basic operations.
CRM 2013: the 4.0 object model goes
Sources: Microsoft’s archived CRM 2013 documentation.
- The CRM 4.0 object model was removed, including
crmForm. Scripts that used it failed after the upgrade. getServerUrlandAuthenticationHeaderwent too, the latter because the 2007 endpoint it existed for was gone.- More were announced for removal:
isOutlookClientandIsOutlookClientOnline, in favour ofclient.getClientandclient.getClientState. Microsoft also saidgetFormTypewould stop returning 5 (Quick Create) and 11 (Read Optimized). - More supported replacements, including
setNotificationandsetFormNotificationfor messages, andaddPreSearchfor filtering lookups.
The CRM 2013 page has the full list.
9.x and Dataverse: formContext
Sources: Microsoft’s current client scripting, formContext and deprecation documentation.
- Get the form from the execution context:
executionContext.getFormContext(), with “Pass execution context as first parameter” ticked on the handler. Ribbon commands receive it as thePrimaryControlparameter instead. Xrm.Pageis deprecated but still supported, and Microsoft commits to at least six months’ notice before removing it. It saysXrm.Pagewon’t go as soon as some other deprecated APIs, because it’s so widely used.- The form context is only valid during the event that passed it. Don’t keep it for later.
Xrm.Page.contextbecameXrm.Utility.getGlobalContext(), with user details underuserSettingsand organization details underorganizationSettings.- HTML web resources lost the easy way in.
parent.Xrmonly works when the web resource is loaded in a form container.
The 9.x on-premises page lists the full deprecation table.
If you’re maintaining old script
- Anything with
crmFormin it has not run since CRM 2013. On a 2011 system it runs only in Internet Explorer, and from Update Rollup 12 only with HTC support switched on. - Upgraded 2011 libraries named after forms, such as
account_main.js, are usually 4.0 code converted into functions, not rewritten. Xrm.Pagecode still runs today, but move anything you touch toformContext, the direction Microsoft has set since 9.0.- Code that reads the DOM or calls undocumented functions has broken at every major step so far and should be treated as broken until tested.
Sources
- Client scripting in Dynamics 365 Customer Engagement (on-premises) Microsoft’s 9.x on-premises client scripting overview. It points to the model-driven apps client API documentation and warns that some client APIs are deprecated in this release, linking to Microsoft’s deprecation announcements.
- Important changes (deprecations) coming in Power Apps and Power Automate Microsoft’s running deprecation list, first published June 2017 and written for the online service. Its section on deprecated client APIs, linked from the 9.x on-premises client scripting page, lists Xrm.Page and its replacements.
- Client API form context (model-driven apps) Microsoft’s formContext documentation: Xrm.Page deprecated in favour of executionContext.getFormContext(), still supported for backward compatibility, at least six months’ notice before any removal, and the “Pass execution context as first parameter” handler option.
- Microsoft CRM 3.0 SDK (compiled help, crmsdk3_0.chm, 2007 edition) Private archive: CRM-SDK-Rescue/3.0-SDK/crmsdk3_0.chm Microsoft’s SDK help for CRM 3.0: the Server Programming Guide’s callout model, method signatures, callout.config.xml reference, error handling and tracing, and the CrmService and MetadataService web services at /mscrmservices/2006/, including security, impersonation, DynamicEntity, FetchXML and QueryExpression. The owner’s copy came from a third-party software archive; it is a valid help file whose 6,937 pages all carry Microsoft’s 2007 copyright. Read as documents only, never executed. Quote sparingly and cite; do not republish.
- Microsoft CRM 3.0 application Help: customization topics Private archive: Microsoft CRM 3.0 Professional server install media (CD 1), wwwroot/Help/PRO/Content Microsoft’s built-in Help for CRM 3.0, read as HTML from the install media: customizing entities, attributes, forms, views and relationships, event scripts (onLoad, onSave, onChange), exporting and importing customizations, and troubleshooting what cannot be customized.
- Microsoft Dynamics CRM 4.0 SDK (compiled help, CrmSdk4.chm, version 4.0.13, November 2010) Private archive: CRM-SDK-Rescue/4.0-SDK/sdk/crmsdk4.chm Microsoft's SDK help for CRM 4.0 Update Rollup 13 and CRM Online: plug-in development (IPlugin, the execution context, the unsecure and secure constructor strings), the event execution pipeline and its parent and child pipelines, registration and deployment, impersonation, error handling, offline plug-ins, execution of CRM 3.0 callouts, the 2006 endpoint, and what is new in the 4.0 web services. Extracted without running anything from CrmSdk4.exe, whose Microsoft Authenticode signature is valid and which the Internet Archive captured from download.microsoft.com. All 12,022 pages carry Microsoft's copyright. Quote sparingly and cite; do not republish.
- Microsoft Dynamics CRM 4.0 application Help: customization and workflow topics Private archive: Microsoft Dynamics CRM 4.0 install media (DVD), Server/i386/wwwroot/help/1033/OP/Content Microsoft’s built-in on-premises Help for CRM 4.0, read as HTML from the install media: customization capabilities and privileges, 1:N, N:1, N:N and self-referential relationships, form scripting, workflows in the web application, duplicate detection, data import, translation of customized text, and the three WSDL files.
- Microsoft Dynamics CRM 2011 SDK (compiled help, CrmSdk2011.chm) Private archive: CRM-SDK-Rescue/2011-SDK_from_desk/SDK/CrmSdk2011.chm Microsoft's own SDK help for the 2011 release, from an owner-held copy. Static reading only; the package is never executed and is not part of this repository. Quote sparingly and cite; do not republish.
- Upgrade scripts to Microsoft Dynamics CRM 2013 (Microsoft Dynamics CRM 2013 SDK, archived) Microsoft’s archived guidance on form script upgrades to CRM 2013: the CRM 4.0 object model (crmForm), the 2007 endpoint, getServerUrl and AuthenticationHeader removed, and the supported Xrm.Page methods that replace common unsupported techniques.
- What’s changing in the next release (Microsoft Dynamics CRM 2013 SDK, archived) Microsoft’s archived CRM 2013 notice of coming changes: the 2007 SOAP endpoint deprecated in CRM 2013 and due for removal in the next release; getServerUrl, isOutlookClient and IsOutlookClientOnline to be removed in favour of getClientUrl, client.getClient and client.getClientState; getFormType no longer returning Quick Create or Read Optimized; old forms removed on upgrade only if deactivated; the Kit product type deprecated; Internet Explorer 8 and 9 support dropped.