Archives

All posts for the month August, 2013

Creating a custom CRM 2011 button that performs JavaScript functions can be tedious in CRM 2011.  Most guides that I found on the internet for CRM 2011 still included the antiquated crmForm.all method, which is unsupported.

So far the best method I have found of adding a button, or multiple buttons, to a form created in Dynamics CRM UR12 and possibly higher, is by utilizing an HTML Web resource that will store a generic button and the JavaScript required to change the functionality/text/etc. Borrowed and adapted from Ray and Razvan on the CRM Development forums

The code for the HTML Web Resource (let’s just call it WebResource_ButtonHTML):

<HTML xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE></TITLE>
<SCRIPT type=text/javascript src="ClientGlobalContext.js.aspx"></SCRIPT>
<SCRIPT type=text/javascript>
    function setText(text) {
        if (text === undefined) {
            text = decodeURI(location.search).replace("?data=", "").replace('%3a', ':').replace('[br]', '<br>');
        }
        var msg = document.getElementById('crmButton');
        msg.value = text;
    }
    //Set the text for the button & attach event
    function initializeButton(text, clickEvent) {
        if (text !== undefined) {
            document.getElementById('crmButton').value = text;
        }
        if (clickEvent !== undefined) {
            try {
                document.getElementById('crmButton').attachEvent("onclick", clickEvent); //Legacy IE code
                    }
    }

    function enable() {
        document.getElementById('crmButton').disabled = false;
    }

    function disable() {
        document.getElementById('crmButton').disabled = true;
    }
</SCRIPT>
<META charset=utf-8></HEAD>
<BODY style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BACKGROUND-COLOR: rgb(246,248,250); MARGIN: 0px; PADDING-LEFT: 0px; FONT-FAMILY: Segoe UI, Tahoma, Arial; COLOR: #3b3b3b; FONT-SIZE: 11px; BORDER-TOP: 0px; FONT-WEIGHT: normal; BORDER-RIGHT: 0px; PADDING-TOP: 0px" onload=setText(); contentEditable=true>
    <BUTTON style="WIDTH: 100%; HEIGHT: 100%" id="crmButton">CRM Button</BUTTON>
</BODY></HTML>

Go into the development page for your form, and then insert this HTML Web Resource and call it ButtonName.  Note that this HTML web resource has code that is normally not supported by CRM 2011 (using the native DOM), but this is okay since this HTML web resource is being used directly and does not have to go through the XRM.Page model.

Now that we have the button that will be inserted onto the frame, we can add custom code in our form’s Javascript library to be able to access the new_ButtonHTML for each button and modify accordingly:

function GetWebResource(name)
{
    try
    {
        var wrt = Xrm.Page.getControl("WebResource_" + name );//automatically adds WebResource_
        if ( wrt != null )
        {
            if ( wrt.getObject().contentWindow.window != undefined )
            {
                return wrt.getObject().contentWindow.window;
            }
            else
            {
                return null;
            }
        }
        else
            return null;
    }
    catch ( e )
    {
        //debugger;
        alert("Error encountered(GetWebResource): " + e.message);
    }
}
var btnName = GetWebResource("ButtonName"); 
if (typeof btnName.initializeButton !== "undefined") {
btnName.initializeButton("Do Stuff", functionToRun); 
}
function functionToRun() {
btnName.disable();
}

The preceding JavaScript defined a function that will check if the web resource has loaded (GetWebResource(“ButtonName”)) and, if the function initializeButton is not undefined, then it will run it and assign it a text value and an event.

Note that with CRM UR12 to UR14 you may have problems with the load order, where initializeButton will sporadically not be defined. If this is the case, you might want to consider setting a timeout to check that the new_ButtonHTML web resource has loaded in the form. That would probably look like this:

function initBtns()  //creating a function so that it can be easily referenced in a timer
{
var btnName = GetWebResource("ButtonName"); 
if (typeof btnName.initializeButton !== "undefined") {
btnName.initializeButton("Do Stuff", functionToRun); 
} else {
setTimeout(initBtns,100); //sets a timeout to run the initBtns function every 100ms
}
}

With these functions, you should be able to reuse the HTML web resource new_ButtonHTML and simply use custom JavaScript to modify them. Make sure that when you add the buttons that you allow the defaults (aside from formatting) such as allowing cross-side scripting or it may not work properly. The page is essentially an iframe or inline frame, hence the GetWebResource function. You might also be able to use other Javascript functions to access the iframe and run the JavaScript for each instance of your new_ButtonHTML.