tags:

views:

717

answers:

4

I'm trying to use the jQuery BlockUI Plugin to block a jQuery dialog while it performs a sorting algorithm. The function that sorts works like this:

doSort : function() {
    $("#sort_dlg").block();

    // sort... takes a few seconds

    $("#sort_dlg").unblock();
}

It works, kind of. The dialog doesn't get blocked until AFTER the sort finishes. (The sort is all done locally, there is no AJAX call or anything.) How do I get it to block BEFORE the sort?

I tried moving the block() call to the OK button method of the dialog:

$(function() {
    $("#sort_dlg").dialog({
        autoOpen: false,
        bgiframe: true,
        modal: true,
        buttons: {
            "Cancel": function() { $(this).dialog("close"); },
            "OK": function() {
                $("#sort_dlg").block();
                doSort();
            }
        }
    });
});

But that didn't help. (I'm open to suggestions for blocking the UI using some other technique.)

A: 

Rather than block the UI, you should disable the dialog using the disable() method the moment the user clicks the "go" button. This way the user can't click anything while the process completes.

Soviut
Thanks, I missed that method. FYI, it has the same issue as BlockUI as mentioned my original question. The setTimeout technique suggested by TheVillageIdiot and Pandincus works to resolve it.
twh
A: 

as pointed by @Pandincus you can wait for some time to let blockUI complete its work and then start sort:

$(function() {
    $("#sort_dlg").dialog({
        autoOpen: false,
        bgiframe: true,
        modal: true,
        buttons: {
            "Cancel": function() { $(this).dialog("close"); },
            "OK": function() {
                $("#sort_dlg").block();
                //WAIT FOR 1 SECOND BEFORE STARTING SORTING
                setTimeout(function(){ doSort()}, 1000);
            }
        }
    });
});
TheVillageIdiot
O noes! Beaten to the punch! :-D Good show, sir.
Pandincus
Thanks guys, this works. Now I have to decide whether to use BlockUI or the disable() method (suggested by Soviut). I'm leaning towards BlockUI because I think it's simpler to tell the user "Please wait...". With disable(), I'm not sure how to do the same without manually inserting a semi-transparent div with "Please wait..." inside.
twh
+1  A: 

To continue my comment above:

When you call $.blockUI(), it uses animations to fade-in the blocking div, and these animations are run asynchronously. The next line in your javascript code is your complex sorting, and this code blocks the browser until it's finished. As a result, the animations that have started running don't get to finish until after the sorting!

The BlockUI plugin doesn't seem to have a callback function option, which is a shame, but that's OK -- we can use Javascript's builtin setTimeout:

<head>
    <title>Test</title>
    <script src="jquery.js"></script>
    <script src="jquery.blockUI.js"></script>
    <script type="text/javascript">
        $(function() {
            $("#btnTest").click(function() {
                $.blockUI();
                setTimeout(doComplicatedStuff, 1000);
            });
        });
        function doComplicatedStuff()
        {
            for(i = 0; i < 100000000; i++)
            {
                // ooh, complicated logic!
            }
            $.unblockUI();
        }
    </script>
</head>
<body>
    <p><input type="button" id="btnTest" value="Test" /></p>
</body>

Although this isn't an exact science, we're basically guessing that delaying the complicated code for 1 second will give BlockUI enough time to display the overlay.

Hope this helps!

Pandincus
A: 

$.blockUI has an option called "fadeIn" that defaults to 200 milliseconds. You can set this value to zero to make the page block occur immediately when the method is called. This disables the fadeIn.

$(function() {
$("#sort_dlg").dialog({
    autoOpen: false,
    bgiframe: true,
    modal: true,
    buttons: {
        "Cancel": function() { $(this).dialog("close"); },
        "OK": function() {
            $("#sort_dlg").block({ fadeIn: 0 }); // disable fadeIn
            doSort();
        }
    }
});
radian21