CRM 2011 SDK version 5.0.6 available

The MS CRM Team have released an updated CRM 2011 SDK version 5.0.6 which can be downloaded here http://www.microsoft.com/download/en/details.aspx?id=24004 or viewed on MSDN here http://msdn.microsoft.com/en-us/library/gg309408.aspx

Some of the additions include:

  • Added Plugin Registration tool support for Windows Azure AppFabric Access Control Services (ACS) 2.0.
  • Updated the AppFabric SDK links and added information on how to use Windows Azure AppFabric ACS 2.0.
  • Added documentation for the Plug-in Profiler tool.
  • Added guidance recommending the use of PNG web resources for icons.
  • Added comment to clarify about the supported use of jQuery.
  • Added guidance for improving performance using the setVisible method.

 

Custom Workflow Activities by Alberto Gemin

Many of you may know of and used the custom workflow plugins developed by Alberto which he had on Codeplex for CRM 4. The great news is that he has updated these custom workflows for CRM 2011 and you can find them from the following links.

CRM 2011 Distribute Workflow Activity
This custom workflow plugin allows you to execute a workflow for each entity that has a 1:N or N:N relationship to a given entity. For example, execute a workflow for each case related to an account (1:N), or for each competitor related to an opportunity (N:N), etc.

CRM 2011 Share Record Code Activity
This custom workflow plugin allows tyou to share any record that can be shared or remove sharing to any record in CRM 2011.

Alberto has an interesting addition to his codeplex gallery titled the CRM 2011 Duplicate Detection Toolkit which you can read about here.

Let’s thank Alberto for his hard work and for sharing these great tools with the CRM community.

You can also find these tools along with more development resources for Dynamics CRM on the Microsoft Dynamics CRM TechNet Wiki here http://social.technet.microsoft.com/wiki/contents/articles/microsoft-dynamics-crm-2011-development-resources.aspx

CRM 2011 Grid with Preview Form

A sample of this html file can be downloaded from my Skydrive here http://sdrv.ms/RbwsKr

 

 

This week I was asked about showing an associated grid view and preview form within a Silverlight application similar to the way Outlook has a grid/preview layout. There are a couple of ways to do this and the one most obvious is to use the Silverlight controls and simply bind the CRM data to them. One alternative I pondered was to reuse the existing CRM Grid and CRM Form in IFrames on a HTML Page. This page could then be loaded into CRM as a Web Resource and opened by a Silverlight application or linked to in SiteMap, etc…

The main advantage to this approach is that any changes to the CRM form fields or grid columns would not require any change to be implemented to this html page, where as using a full Silverlight app you would have to update the application aswell. I’m going to show you the pieces of the prototype I built and hopefully you may be able to take this further for your own benefit. Here is a screenshot of the layout of the html page.

The html body consists of 2 iframes, one for the grid and the other for the form. In this example the grid is loading the Contact’s Activities associated grid view.

<body onload="Initialise()">

</body>

I have a number of constants for this prototype demo but some of these you will want to determine from a querystring or ClientGlobalContext.js.aspx file,

// You should collect the the server address and org values using the ClientGlobalContext.js.aspx file <a href="http://msdn.microsoft.com/en-us/library/gg328541.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/gg328541.aspx</a>
var server = "http://crm:5555"; // server url with port, if port required
var orgName = "Playground";

//  grid related settings
var entityId = "<A Guid Value goes here>"; // e.g. 00000000-0000-0000-0000-00000000000
var entityType = "2"; // Entity type for Contact
var areaView = "areaActivities"; // Activities associated view id found in Left hand Nav Pane by viewing DOM
//var areaView = "areaOpps"; // Opportunities associated view id found in Left hand Nav Pane by viewing DOM
var internalGridElement = "crmGrid_Contact_ActivityPointers"; // Activity Grid found in DOM
//var internalGridElement = "crmGrid_opportunity_customer_contacts"; // Opportunity Grid found in DOM

The body onload simply calls Initialise which sets the uxGrid iframe.

// Initialise page, set grid iframe
function Initialise() {
    document.getElementById("uxGrid").src = server + "/" + orgName + "/userdefined/areas.aspx?oId=%7b" + entityId + "%7d&oType=" + entityType + "&security=000000&tabSet=" + areaView;
}

When the grid loaded and when I selected a new view on the grid I received the ‘Error on Page’ and after tracing through the script I found that I could simply provide some stubs which handle the calls executed by the grid. I return null and I haven’t seen any functional issues arise from this during my testing.

// Stubs to handle grid in an IFRAME, errors occur otherwise
var Mscrm = new Object();
Mscrm.PageManager = new Object();
Mscrm.PageManager.get_instance = function() { return null; }

var crmRibbonManager = null;

$find = function(e) {
    return null;
}
// End Stubs

The following functions provide the functionality for the form preview to load. LoadPreviewPane is called when you single click a row in the grid. CleanFormWindow removes the form ribbon, left hand nav pane, footer and also disables all fields on the form.

// Show form in preview area
function LoadPreviewPane(entity) {
if (entity != null) {
document.getElementById("uxPreview").style.visibility = "hidden";
document.getElementById("uxPreview").src = server + "/" + orgName + "/main.aspx?etn=" + entity.TypeName + "&extraqs=" + escape("&id=" + entity.Id) + "&pagetype=entityrecord";
}
else {
document.getElementById("uxPreview").src = "about:blank";
}
}

// Remove chrome from around form in preview area
function CleanFormWindow() {
    if (event.srcElement.readyState == "complete") {
        var frameDoc = document.getElementById("uxPreview").contentWindow.document;

        if (frameDoc && frameDoc.getElementById("contentIFrame")) {
if(frameDoc.getElementById("perceivedRibbonId")) frameDoc.getElementById("perceivedRibbonId").style.display = "none";
frameDoc.getElementById("crmTopBar").style.display = "none";
 frameDoc.getElementById("crmContentPanel").style.top = "0px"; // Move Form Content area up to top of window, initial style.top is 135px
 frameDoc.getElementById("crmContentPanel").style.height = "100%";
 frameDoc.getElementById("contentIFrame").style.height = "100%";

 frameDoc.getElementById("contentIFrame").onreadystatechange = function() {

 if (frameDoc.getElementById("contentIFrame").readyState == "complete") {
 try {
 // Hide Left Hand Nav bar / pane
 frameDoc.getElementById("contentIFrame").contentWindow.document.getElementById("crmNavBar").parentElement.style.display = "none";
 frameDoc.getElementById("contentIFrame").contentWindow.document.getElementById("tdAreas").parentElement.parentElement.parentElement.parentElement.colSpan = 2;
 frameDoc.getElementById("contentIFrame").contentWindow.document.getElementById("tdAreas").parentElement.parentElement.parentElement.parentElement.style.height = "100%";

 // Hide the Breadcrumb and Record Set Toolbar
 frameDoc.getElementById("contentIFrame").contentWindow.document.getElementById("recordSetToolBar").parentElement.style.display = "none";

 // Hide the Form Footer Bar
 frameDoc.getElementById("contentIFrame").contentWindow.document.getElementById("crmFormFooter").parentElement.style.display = "none";

 // make everything readonly on the form using Xrm.Page controls
 frameDoc.getElementById("contentIFrame").contentWindow.Xrm.Page.ui.controls.forEach(SetControlDisabled);

 // Everything is finished so show the form
 document.getElementById("uxPreview").style.visibility = "visible";
 } catch (ex)
 { }
 }
 }
 }
 }
}

// Delegate function for disabling control in form control collection
function SetControlDisabled(control,index)
{
control.setDisabled(true);
}

The AttachGridEvent function attaches the GridClick function to the onselectionchange event of the internalGridElement defined in the constants earlier. A line of code sets the grid to single row selection to prevent a user from selecting multiple rows.

function AttachGridEvent() {

if (document.getElementById("uxGrid").readyState == "complete") {
var frameDoc = document.getElementById("uxGrid").contentWindow.document;
if (frameDoc.getElementById(internalGridElement) != null) {
frameDoc.getElementById(internalGridElement).attachEvent("onselectionchange", GridClick);
// Set grid to single select
if(frameDoc.getElementById(internalGridElement).document.getElementById("max"))
frameDoc.getElementById(internalGridElement).document.getElementById("max").value = 1;
}
}
}
// GridClick function for onselectionChanged event
var bFired = false;
function GridClick() {
selectedItems = new Array();

var grid = null;

//    get array of selected records
var frameDoc = document.getElementById("uxGrid").contentWindow.document;

if (bFired == false) {

if (frameDoc.getElementById(internalGridElement)) {
grid = frameDoc.getElementById(internalGridElement).control;
if (grid.get_selectedRecordCount() > 0) {
var records = grid.get_selectedRecords();
// record object fields
// Id
// Name
// TypeCode
// TypeName
LoadPreviewPane(records[0]);
}
else {
LoadPreviewPane(null);
}
}
bFired = true;
}
else {
bFired = false;
}
}

Hopefully you are able to reconstruct a html page from these examples and remember you must import the html page as a Web Resource otherwise you will end up with a cross domain error.

CRM 2011 Rollup 3 now available

The Microsoft Dynamics CRM Sustained Engineering (SE) team have been hard at work to get the UR3 release to us all so please take alook at the CRM Team blog for further details. http://blogs.msdn.com/b/crm/archive/2011/06/02/update-rollup-3-for-microsoft-dynamics-crm-2011.aspx

 

CRM 2011 SDK version 5.0.5 available

The MS CRM Team have released an updated CRM 2011 SDK version 5.0.5 which can be downloaded here http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69 or viewed on MSDN here http://msdn.microsoft.com/en-us/library/gg309408.aspx

Check out the CRM Team blog for further details about the release http://blogs.msdn.com/b/crm/archive/2011/06/06/announcing-microsoft-dynamics-crm-sdk-update-v5-0-5.aspx

 

Also note that the Developer Toolkit for Visual Studio is included in this release.