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>, value became DataValue, and date fields accepted only a Date object.
  • OnSave fires even when nothing changed. It can cancel the save with event.returnValue = false, and event.Mode tells Save (1) from Save and Close (2).
  • 4.0 added globals: SERVER_URL, ORG_UNIQUE_NAME, USER_LANGUAGE_CODE and ORG_LANGUAGE_CODE, and the functions IsOnline, IsOutlookClient, IsOutlookLaptopClient, IsOutlookWorkstationClient, PrependOrgName and GenerateAuthenticationHeader. 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, .js or .htm files;
  • 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.Page arrived with capabilities crmForm couldn’t offer: showing and hiding parts of the form, several controls per attribute, several forms per entity, and navigation items. It splits into context, data and ui.
  • crmForm was 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. The crmForm calls inside were left as they were. Watch for doubled handlers: if you later install a solution that handles the same events with Xrm.Page code, 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, getDepth and getSharedVariable and setSharedVariable for sharing values between handlers.
  • Supported replacements for old hacks. The SDK lists methods such as addCustomView and setDefaultView for lookups, setLabel, setVisible, setFocus, setRequiredLevel, addOnChange and addOnSave. 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.aspx still worked, but main.aspx?etn=account&pagetype=entityrecord was 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.
  • getServerUrl and AuthenticationHeader went too, the latter because the 2007 endpoint it existed for was gone.
  • More were announced for removal: isOutlookClient and IsOutlookClientOnline, in favour of client.getClient and client.getClientState. Microsoft also said getFormType would stop returning 5 (Quick Create) and 11 (Read Optimized).
  • More supported replacements, including setNotification and setFormNotification for messages, and addPreSearch for 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 the PrimaryControl parameter instead.
  • Xrm.Page is deprecated but still supported, and Microsoft commits to at least six months’ notice before removing it. It says Xrm.Page won’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.context became Xrm.Utility.getGlobalContext(), with user details under userSettings and organization details under organizationSettings.
  • HTML web resources lost the easy way in. parent.Xrm only 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 crmForm in 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.Page code still runs today, but move anything you touch to formContext, 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

  1. Client scripting in Dynamics 365 Customer Engagement (on-premises) Microsoft · · Primary, current docs 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.
  2. Important changes (deprecations) coming in Power Apps and Power Automate Microsoft · · Primary, current docs 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.
  3. Client API form context (model-driven apps) Microsoft · · Primary, current docs 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.
  4. Microsoft CRM 3.0 SDK (compiled help, crmsdk3_0.chm, 2007 edition) Microsoft · Primary, archived 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.
  5. Microsoft CRM 3.0 application Help: customization topics Microsoft · Primary, archived 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.
  6. Microsoft Dynamics CRM 4.0 SDK (compiled help, CrmSdk4.chm, version 4.0.13, November 2010) Microsoft · Primary, archived 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.
  7. Microsoft Dynamics CRM 4.0 application Help: customization and workflow topics Microsoft · Primary, archived 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.
  8. Microsoft Dynamics CRM 2011 SDK (compiled help, CrmSdk2011.chm) Microsoft · Primary, archived 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.
  9. Upgrade scripts to Microsoft Dynamics CRM 2013 (Microsoft Dynamics CRM 2013 SDK, archived) Microsoft · · Primary, 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.
  10. What’s changing in the next release (Microsoft Dynamics CRM 2013 SDK, archived) Microsoft · · Primary, 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.