Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamics 2013 Accessing Page entities is hard to access with iframe based views

I am building an angular application which is running as a web resource on Dynamics 2013.

The application runs using a button which is added to the commandContainer using Ribbon workbench which then that button calls a Xrm.Internal.openDialog

All this works fine until I want to start using the Entities exposed by Xrm.Page.Data

Basically my button runs in the context of the main page of dynamics however the Entities are inside an iframe which based on the page I am in has a different Id and name.

So using a simple selector I can not get its contentWindow and start using the Entities.

The #crmContentPanel always has few iframes in it starting from #contentIFrame0 to #contentIFrame(n) and I can never know which iframe is the one with Entities in it.

What is the best practice, associated work flow with developing applications in this environment? How can I easily and reliably access the correct frame which holds the main page entities and work with them.

Perhaps the script is in the wrong location and needs to injected into the main content area so it has direct access to the correct Xrm? How can I achieve that?

Furthermore once I eventually manage to access this data, how can I easily pass this data to my angular application which runs in the dialog as from the documentation I read that the dialog is only allowed 1 query string param and it has to be called data. That would not be enough for my application to start using $routeParams. And I don't think using local or session storage is nice practice. What is the correct approach in this situation.

Sample code of my button script:

function runSendSender() {

    // Content Iframe Entity data:
    var contentFrameXrm = $('#crmContentPanel')
                       .find("iframe#contentIFrame0...n")[0]
                       .contentWindow['Xrm'];

    // even if above selector was consistent across pages
    // I need to send over much more than this one Id :(
    var data = contentFrameXrm.Page.data.entity.getId();

    var src = "/WebResources/concep_/ConcepDynamicsApp/ConcepDynamicsApp.html?data=" + data;
    var DialogOptions = new Xrm.DialogOptions();
    DialogOptions.width = 800;
    DialogOptions.height = 500;
    Xrm.Internal.openDialog(src, DialogOptions, null, null, CallbackFunction);

    function CallbackFunction(returnValue) { }
}

Little more detail

When I type the following in the console I can sometimes (randomly) read the title of the form:

$('#crmContentPanel').find("iframe#contentIFrame0")[0].contentWindow['Xrm'].Page.ui.get_formTitle();

But the same code from the associated web resource function can not access the iframe and errors:

Can not Cannot read property 'contentWindow' of undefined.

Why is the iframe not accessible via the resource script and how can I access the correct context and form title/id.

like image 646
Ali Habibzadeh Avatar asked Sep 05 '14 09:09

Ali Habibzadeh


1 Answers

I'm usually including following JavaScript file to the header of the custom WebResource that need to have an access to the CRM specific actions / information:

<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>

This gives access to some none-entity specific information, such as Xrm.Page.context.getServerUrl() or Xrm.Page.context.getUserId() for example.

But if you added layer with your own iFrame on top of the standard entity page, you definitely can access to information underneath your current context by using following construction:

window.parent.Xrm.Page.data.entity.attributes.get("name").getValue();

Note the window.parent prefix.

like image 148
shytikov Avatar answered Sep 22 '22 20:09

shytikov