Wednesday, September 16, 2009

MSCRM 4.0: Show Entity’s Associated View in IFrame

While Jim Wang, Matt Wittemann, and many others have posted the code to load an associated view in an iframe on a CRM form, I am trying to give a self-contained JavaScript function to handle this requirement, with one tiny enhancement.

The following is the script that I have evolved based on the scripts that I have just mentioned.

/**
 * Load an associated view into an IFrame while hiding it from LHS navigation menu. 
 * @author Daniel Cai, http://danielcai.blogspot.com/
 * 
 * Parameters:
 * @param iframe:      The IFrame's object, e.g. crmForm.all.IFrame_Employer_Address
 * @param navItemId:   LHS navigator's HTML element ID of the associated view.
                       It usually starts with "nav".
 */
function loadAssociatedViewInIFrame (iframe, navItemId)
{
    var clickActionPattern =  /loadArea\(['"]{1}([A-Za-z0-9_]+)['"]{1}(, ?['"]\\x26roleOrd\\x3d(\d)['"])*\).*/;   

    var getFrameSrc = function (areaId, roleOrd)
    {
        var url = "areas.aspx?oId=" + encodeURI(crmForm.ObjectId);
        url += "&oType=" + crmForm.ObjectTypeCode;
        url += "&security=" + crmFormSubmit.crmFormSubmitSecurity.value;
        url += "&tabSet=" + areaId;
        url += (!roleOrd) ?  "" : "&roleOrd=" + roleOrd;

        return url;
    };

    var onReadyStateChange = function() {
        if (iframe.readyState === 'complete') {
            var frameDoc = iframe.contentWindow.document;

            // Remove the padding space around the iframe
            frameDoc.body.scroll = "no";
            frameDoc.body.childNodes[0].rows[0].cells[0].style.padding = "0px";

            iframe.detachEvent('onreadystatechange', onReadyStateChange);
        }
    };

    (function init() {
        if (!crmForm.ObjectId) return;

        var navItem = document.getElementById(navItemId);
        if (!navItem) return;

        var clickAction = navItem.getAttributeNode('onclick').nodeValue;  
        if (!clickAction || !clickActionPattern.test(clickAction))  
            return;  
 
        var areaId = clickAction.replace(clickActionPattern, '$1');  
        var roleOrd = clickAction.replace(clickActionPattern, '$3');

        navItem.style.display = 'none';

        iframe.src = getFrameSrc(areaId, roleOrd);
        iframe.allowTransparency = true; // Get rid of the white area around the IFrame
        iframe.attachEvent('onreadystatechange', onReadyStateChange);
    })();
};
The tiny enhancement I mentioned was, the script tries to make the IFrame transparent so you won’t see a white-color area around the IFrame.


To use the above function, you may make a call like the following snippet:
loadAssociatedViewInIFrame(crmForm.all.IFRAME_Accounts, "navnew_account_new_project");
In the above snippet, IFRAME_Accounts is the iframe that I am using to load the associated view, while navnew_account_new_project is the ID of the left navigation item which you can click to navigate to the associated CRM view.

[Update - Mar 27, 2010] I updated the code with some little enhancements while I was writing another blog post about removing "Add Existing" button from the associated view.

[Update - Feb 08, 2010] I updated the code a little bit, while I was writing another blog post today, so it now requires only two parameters instead of the previous three. I know it's a little silly to update a blog post that is almost one and half years old. My intention is to have a script that either looks better or works better if I see that kind of opportunity. ;-)

No comments:

Post a Comment