How to get formContext in Ribbon command of Dynamics 365 9.0

In Dynamics 365 9.0 there was quite a big change regarding how to access form attributes and controls - instead of Xrm.Page namespace, we should pass executionContext to a function and get formContext using getFormContext() function. This is working fine and I had never a problem with using this approach.

However I did not figured out yet how to properly access formContext in functions that are called from Ribbon. The documentation says that this should be really straightforward:

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/customize-dev/pass-dynamics-365-data-page-parameter-ribbon-actions

function myFunction(executionContext) {
    var formContext = executionContext.getFormContext();
    var focusFieldValue = formContext.ui.controls.get(PrimaryControlId).getAttribute().getValue();
}

But it does not say how to pass executionContext to Ribbon function. In normal functions there is a checkbox "Pass execution context as first parameter" but what about Ribbon functions? There are parameters that we can pass into these functions, but they are simply GUID of selected records, or type of selected record or even a list of objects but I could not find in documentation, if there is a parameter equal to executionContext. Has anybody already solved this problem?

Also I know that I can use Xrm.Page and it will work (for now at least...) but I would like to know, how it can be done using the latest guidelines in version 9.0

Update 1:

As per Scott's suggestion and this article i passed PrimaryControl to my Ribbon command but unfortunately, the argument is of type Mscrm.FormControlLite and it does not have getAttribute function or any function that would allow to access the formContext (at least I don't see anything useful). Some screenshot from Developer tools:

So it looks like a form representation of some kind, but is probably not related to formContext (I assume that if a Ribbon would be called from a list of records, this item can be of type of grid or something like that)

As per https://docs.microsoft.com/en-us/dynamics365/get-started/whats-new/customer-engagement/important-changes-coming#some-client-apis-are-deprecated you pass it as the PrimaryControl parameter.

So if you pass the PrimaryControl as the second parameter to a command function like this you can use

arguments[1].getAttribute(…)

Getting Dynamics 365 formContext from Ribbon Workbench , I've chosen to modify the Command for this custom Name button: Now after selecting the Add Parameter, we select CRM Parameter: And then  When we select Customise Command in Ribbon Workbench we can pass Execution Parameters. I’ve chosen to modify the Command for this custom Name button: Now after selecting the Add Parameter, we select CRM Parameter: And then select Primary Control: Now you can get formContext from this parameter as easily as if it were the executionContext.

After passing the primaryControl as @scott-durow suggested, It is best to not use primaryControl.getFormContext() and instead use the primaryControl as though it is the formContext.

According to the documentation (1/2/2019): https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/customize-dev/pass-dynamics-365-data-page-parameter-ribbon-actions#form-and-grid-context-in-ribbon-actions, one should perform operations on the primaryControl as though it is the formContext.

function mySampleFunction(primaryControl) {
    var formContext = primaryControl;
    // Perform operations using the formContext object
}

But, the key piece of the example provided is this: // Perform operations using the formContext object being the key (no idea why they added the var formContext = primaryControl line, imo, it would have been clearer if they had instead just shown an example: primaryControl.getAttribute('xxxx');

I suspect primaryControl.getFormContext() code started getting used because thats how you get the formContext when working with forms (https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/clientapi-form-context#using-the-formcontext-object-instead-of-the-xrmpage-object).

The problem with using primaryControl.getFormContext() is that it works with the normal Web interface, but breaks with the UCI. But if you use primaryControl as though it is the form-context, then it works for both the legacy web-client and uci interfaces.

Here is a function that I use:

function getFormContext(executionContext) {
     var formContext = null;
     if (executionContext !== null) {
         if (typeof executionContext.getAttribute === 'function') {
             formContext = executionContext; //most likely called from the ribbon.
         } else if (typeof executionContext.getFormContext === 'function' 
                 && typeof(executionContext.getFormContext()).getAttribute === 'function') {
            formContext = executionContext.getFormContext(); // most likely called from the form via a handler
         } else {
            throw 'formContext was not found'; //you could do formContext = Xrm.Page; if you like.
        }
    }
    return formContext;
}

Get formContext in Ribbon Command, We all know that there are lot of changes to Dynamics 365 JavaScript in accessing form attributes and controls. We should pass executionContext  Now I can have the formContext directly, just from a subgrid ribbon button, to the main entity Case: var caseTitle = selectedControl.formContext.getAttribute(“title”).getValue(); My Dynamics 365 version is Version 1710 (9.1.0.8422) online

I was having the same issue as well. What I found out was, there was an error in Microsoft doco. Please follow whatever Scott mentioned passing CRM Parameter from ribbon command action. In javascript function, please try below to get form context

var formContext = primaryControl.getFormContext();

this fixed my issue.

How to pass execution context as a parameter in Ribbon Workbench , To use formContext instead of Xrm.Page in v9 for example You have to update your ribbon workbench command to add a CRM parameter "PrimaryControl" as  So the next question lies on how to pass executionContext parameter to your Ribbon actions. For that you need to pass the CrmParameter – Primary control to your ribbon action. Below is the code to get the data using formContext. function ribbonHandler(fc) {var formContext = fc; var recordId = formContext.data.entity.getId();

There is a little trick you can do to not have to pass the Primary Control as Crm Parameter with the RibbonWorkbench utility, or if having done this, it would not be working for you, as it could happend if you were trying this in a home-grid ribbon.

var context=Xrm.Utility.getGlobalContext();

I hope this works for you or anyone else.

Getting Form Context from Sub-grid ribbon button in Dynamics V9.0 , Docs · Dynamics 365 · Customer Engagement (on-premises), version 9 When you define an action in a ribbon, you frequently have to pass data This argument provides the form context where the ribbon command is executed: Customize the Ribbon for Microsoft Dynamics 365 Customer Engagement In Dynamics 365, the formContext provides a reference to a form or form item through JavaScript. The formContext is part of executionContext, and replaces Xrm.Page which is deprecated in version 9+ of Dynamics 365. The form context object model looks like: Let’s go through an example of using the formContext.

Pass Customer Engagement data from a page as a parameter to , In Dynamics 365 9.0 there was quite a big change regarding how to access form attributes and controls - instead of Xrm.Page namespace, we should pass  Client API form context. 04/10/2019; 2 minutes to read; In this article. The Client API form context (formContext) provides a reference to the form or to an item on the form, such as, a quick view control or a row in an editable grid, against which the current code is executed.

Formcontext, Get formContext in Ribbon Command - Dynamics 365 9. Provides properties and methods to retrieve information formContext. In case your ribbon button is on  formSelector is not available for Microsoft Dynamics 365 for tablets. navigation: An object containing a property items, which is a collection of all the navigation items on the page. See Collections for information about the collection methods and formContext.ui.navigation item for information about the items in the collection.

JavaScript: "Execution Context" provides Form Values on Web as , No doubt, Microsoft Dynamics 365 v9.0 surprised us with the UCI feature and got the “executionContext” in script and get the form context. In Dynamics 365 9.0 there was quite a big change regarding how to access form attributes and controls - instead of Xrm.Page namespace, we should pass executionContext to a function and get formContext using getFormContext() function. This is working fine and I had never a problem with using this approach.

Comments
  • Thanks Scott for reaching out! Unfortunately when I pass PrimaryControl it is of type Mscrm.FormControlLite and it does not have getAttribute method or anything I can see that can be used to replace Xrm.Page (I updated my question). Based on the article you posted it should work this way, so that's strange...
  • Are you calling a command from a form or grid button? In a form context inside the Unfiied Client I've used this technique successfuly in Version 1612 (9.0.0.3172) (DB 9.0.0.3172) online
  • Unified Interfce is the key word here :) You are right, it works in UI, I hope that they will make it also work in normal web client...
  • Unfortunately, there are still many differences between the Web and the UUI - maybe use something like var formContext = primaryControl.ui ? primaryControl : Xrm.Page
  • Yes, I eventually ended up doing so, thanks for the help!
  • Link to documentation as of when this is true (as v9 js seems to be changing often and this may not be true forever) github.com/MicrosoftDocs/dynamics-365-customer-engagement/blob/…
  • Indeed MS docs are wrong in this link docs.microsoft.com/en-us/dynamics365/customer-engagement/… in the area with function mySampleFunction(primaryControl) :(
  • Specifically how would you migrate from Xrm.Page.context.getQueryStringParameters().etc; ?
  • (answering own question above) -> that goes to this: var formContext = primaryControl.getFormContext(); followed by formContext.context.getQueryStringParameters().etc..... so far it looks like anywhere you have Xrm.Page, just put the formContext in its place (after receiving it in the function param)
  • What I found is that "primaryControl.getFormContext();" works only in the web interface and does not work with UCI. Use primaryControl as though it is the form context. This will make your code work in both the web and UCI. (docs.microsoft.com/en-us/dynamics365/customer-engagement/…)
  • @mmcrae, your code, breaks with the UCI. it is better to just do: primaryControl.context.getQueryStringParameters() (true as of v9.1.0.1006), which works for both the web and UCI