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(…)
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.
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;
}