Creating a Loading Panel in Dynamics CRM Forms

On many occasions, I had to create ribbon button to perform business logic that sometimes takes time to complete and/or execute. One of the comment that I always get in these situations is that it’s annoying from an end user’s perspective not to know what is happening. This is true, the UI kind of freezes for a few seconds and then everything comes back to normal, users are never sure what to do during this time and it sometimes results on them trying to refresh the page or click on the button multiple times. Here I am sharing one way to build a modal loading panel on top of a CRM form that I use very often. It’s a fairly simple thing to do if you are opened to using jQuery.

The idea is to use jQuery to add a hidden HTML block (the loading panel) to the CRM form, this is done in the function called InitializeLoadingPanel. Then you add 2 methods, one to show the HTML block and another one to hide it. You can refer to the Jscript code below for the 3 functions.

function InitializeLoadingPanel() {

    if ($("body").find("#panel").length > 0) {

    var displayText = "Working...";

    // Loading Panel
    $('body').append('<div id="panel"></div>');

    // Loading Panel Content Div
    $('body').append('<div id="contentDiv"></div>');

               .css({ 'position': 'absolute', 'top': '0', 'left': '0', 'width': '100%', 'height': '100%', 'background-color': '#FFFFFF' });

     $("#contentDiv").append('<p id="loadingText">' + displayText + '</p>')
                    .css({ 'background-color': '#DDDDDD', 'height': '100px', 'width': '300px' });

    // Setup your text css
    $("#loadingText").css({ "text-align": "center", "margin-top": "50px", "font": "12px bold" });


// Open the Loading Panel
function OpenLoadingPanel(callback) {

    // Make sure you Initialize the loading panel
    if ($("body").find("#panel").length <= 0) {

    var panel = $("#panel");
    var panelContent = $("#contentDiv");
    var pageHeight = $(document).height();
    var pageWidth = $(window).width();

    panelContent.css("position", "absolute");
    panelContent.css("top", ((pageHeight - panelContent.outerHeight()) / 2) + $(document).scrollTop() + "px");
    panelContent.css("left", ((pageWidth - panelContent.outerWidth()) / 2) + $(window).scrollLeft() + "px");

    panel.css({ "z-index": 1000 });
    panelContent.css("z-index", 1001);

    if (callback != null) {
        panel.fadeTo("fast", 0.8, function () {
            panelContent.fadeIn(10, function () {
                setTimeout(callback, 10);
    else {
        panel.fadeTo("fast", 0.8, function () {

// Close the Loading Panel by hiding it
function CloseLoadingPanel() {

    $("#contentDiv").fadeOut("fast", function () {
        $("#panel").fadeOut(0, function () {

That’s good for starters. Now in order to test this, I have written a very simple function that simple opens the loading panel and sleeps for a few seconds in order for us to see the loading panel on the screen.

// In this example, I call this method on the OnChange event of a custom field in order
// to display the loading panel. In the past, I've had to use this in different cases
// from ribbon button to on change of field value. It really depends on what you are doing in your
// Javascript code.
function DisplayLoadingPanel() {

    window.setTimeout(CloseLoadingPanel, 6000);

And now let’s take a look at the result. As I am mentioning in the comments on the code block above, in this example I set the DisplayLoadingPanel method to be called on the On Change event of a field on my form. Typically, you can have the loading panel displayed whenever you need. Here is what it looks like:

You can play around with the css to add an image to the loading block and do all sorts of things with the look and feel. This is all supported in theory (my example is running in CRM Online). Note that in order for this to work, you need to have a Jscript web resource with jQuery registered in the form before the script in which the loading panel is initialized, displayed and hidden.

Hope this helps!