Reputation: 24529
I currently have this type of layout:
+---------------+
| hide/show | <-- button
+---------------+
+---+ +---+ +---+
| 1 | | 2 | | 3 | <- widgets
+---+ +---+ +---+
+---+ +---+ +---+
| 4 | | 5 | | 6 |
+---+ +---+ +---+
+---+ +---+ +---+
| 7 | | 8 | | 9 |
+---+ +---+ +---+
Within each widget, i have a 'close button':
+-------------------------------------------+
| \ /|
| HEADING X | <--'close widget' button
| / \|
+-------------------------------------------+
| _/
| CONTENT ___/
| _______/
| __________/
| /
|_________________/
I am using Jquery's 'toggle' effect to achieve this.
However, the big button (Hide/Show
) is used to hide/show all of them. (all hidden, all shown)
I can't seem to work out how to do this :(
Currently i have this jsfiddle showing if I close a couple of them, and hit the toggle all button, it will close the rest on screen, and show the one's i've just closed (not wanted).
I want this button to show all (or hide all) depending on if
(a) they are all hidden, then show all or
(b) if some are hidden, then show them.
(c) if all are shown, then hide all.
How can I get this functionality?
(wanted but not necessarily required)
On the 'show', how can I get them to show div1 first, then div2, then div3/etc until all are shown? (i.e. toggle them in sequence)
Upvotes: 2
Views: 183
Reputation: 4826
Since slideToggle()
doesn't care about the state of each individual widget, you're going to have to manually keep track of whether all widgets should be open or closed -- thereby defeating the purpose of using slideToggle()
!
$('#widgetToggle').on('click', function () {
var $widgets = $('.widget');
if ($widgets.filter(':visible').length == $widgets.length) {
$widgets.slideUp();
} else {
showInSequence($widgets.filter(':hidden'));
}
return false;
});
function showInSequence($el) {
if ($el.length) {
$el.first().slideDown(function () {
showInSequence($el.filter(':hidden'));
});
}
}
Upvotes: 3
Reputation: 45121
Try this.
$('#widgetToggle').click(function () {
var widgets = $('.widget'),
total = widgets.length,
visible = widgets.filter(':visible').length,
//hide if all are visible
method = total === visible ? 'slideUp': 'slideDown',
run = function() {
var first;
if(widgets.length) { //there is something left
first = widgets.first(); //save first
widgets = widgets.slice(1); //remove processed
first[method](run); //show hide
}
};
run();
});
Demo.
Upvotes: 2