BlockUI takes too long to block jQuery dialog
Asked Answered
A

4

5

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.)

Aldwon answered 14/10, 2009 at 3:59 Comment(1)
This is probably because blockUI uses animations to fade-in the modal popup, and while these animations are running asynchronously, your sort code begins to run. Since your sort code is running synchronously on your page, the browser is blocked until the sort code is finished. Your answer is to use a callback function, which I'm looking into right now ...Osteopathy
A
6

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);
            }
        }
    });
});
Angelo answered 14/10, 2009 at 4:17 Comment(1)
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.Aldwon
F
6

$.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();
        }
    }
});
Frodine answered 30/8, 2010 at 21:26 Comment(1)
+1 - Thanks a lot man! Your fadeIn thing did magic for my problem :)Pachalic
O
4

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!

Osteopathy answered 14/10, 2009 at 4:19 Comment(0)
S
0

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.

Sync answered 14/10, 2009 at 4:15 Comment(1)
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.Aldwon

© 2022 - 2024 — McMap. All rights reserved.