Connie DeCinko Connie DeCinko - 1 month ago 8
CSS Question

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;
}
}

Answer

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/