Connie DeCinko
Connie DeCinko

Reputation: 1036

Hide several divs and only after all are hidden, then run a callback function

I am needing to hide all of the divs of class .panel in a container div. Then after all are hidden, selectively unhide a few of the .panel divs. I tried using a callback on hide() but the callback runs for every single element that is hidden. In some cases I end up in a nearly infinite or long running loop as the same divs are hidden and shown over and over.

This does not work as the second elements are being shown before the hide is complete:

$("#detailsPanel").children(".panel").hide();
$("#membershipPanel").slideDown();
$("#specializationsPanel").slideDown();

And if I nest those steps after the hide in a callback, the call back runs for every .panel div that is hidden.


FULL CODE

Here is my full function if that helps to find the flaw in my logic.

function goWizard(step) {
    switch (step) {
        case 0:
            $("#formPanel").hide();
            $("#beginPanel").slideDown();
            $("#instructionsPanel").slideDown().children().slideDown();
            $("#loginPanel").slideDown().children().slideDown();
            break;
        case 1:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Membership Category/Specialist Category :: Step 1 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#membershipPanel").show();
                    $("#specializationsPanel").show();
                }
            });

            $("#startOverButton").show();
            $("#prevStepButton").hide();
            $("#nextStepButton").show();
            $("#startOverButton").click(function () { goWizard(0); });
            $("#nextStepButton").click(function () { goWizard(2); });
            break;
        case 2:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Section Membership :: Step 2 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#sectionsPanel").show();
                }
            });

            $("#startOverButton").hide();
            $("#prevStepButton").show();
            $("#nextStepButton").show();
            $("#prevStepButton").click(function () { goWizard(1); });
            $("#nextStepButton").click(function () { goWizard(3); });
            break;
        case 3:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Insurance Compliance :: Step 3 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#insurancePanel").show();
                }
            });

            $("#startOverButton").hide();
            $("#prevStepButton").show();
            $("#nextStepButton").show();
            $("#prevStepButton").click(function () { goWizard(2); });
            $("#nextStepButton").click(function () { goWizard(4); });
            break;
        default:
            $("#beginPanel").slideDown();
            $("#formPanel").hide();
            break;
    }
}

Upvotes: 1

Views: 461

Answers (3)

taseenb
taseenb

Reputation: 1443

Given a DOM structure like (example):

<div class="panel">text</div>
<div class="panel unhide">text</div>
<div class="panel">text</div>
<div class="panel unhide">text</div>
<div class="panel">text</div>

You can hide and then unhide the elements in 2 ways with jQuery.

Either:

$.when($('.panel').animate({opacity: 0}, 500)).then(function () {
  $('.unhide').animate({opacity: 1}, 500);
});

Or:

$('.panel').animate({opacity: 0}, 500).promise().done(function () {
  $('.unhide').animate({opacity: 1}, 500);
});

https://jsfiddle.net/q2mctsz6/

Upvotes: 0

Jason P
Jason P

Reputation: 27012

I would use promises:

$.when(
    $("#detailsPanel").children(".panel").hide().promise(),
    $("#membershipPanel").slideDown().promise(),
    $("#specializationsPanel").slideDown().promise()
).done(function() {
    console.log('all done');
});

Example: https://jsfiddle.net/jjh65h2y/

Upvotes: 3

Tyler Roper
Tyler Roper

Reputation: 21672

You could modify your hide callback to check if the element being hidden is the last one, and then do the callback in that portion, like so...

var i = 0;
var $panels = $("#detailsPanel").children(".panel");
$panels.hide(function() {

    i++;
    if(i == $panels.length) {
        $("#membershipPanel").slideDown();
        $("#specializationsPanel").slideDown();
    }

});

Upvotes: 0

Related Questions