jbutler483
jbutler483

Reputation: 24529

SlideToggle multiple divs in sequence

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                          ___/
|                              _______/    
|                   __________/                                                      
|                  /           
|_________________/                        

Main Issue


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?


Side Issue

(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

Answers (2)

Rodney G
Rodney G

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

Yury Tarabanko
Yury Tarabanko

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

Related Questions