web-dev-qa-db-fra.com

accordéon jQuery UI Expand/Collapse All

J'utilise l'accordéon jQuery UI (ce qui fait n'autorise pas l'ouverture d'un seul élément à la fois ) sur un projet. Utiliser accordéon est approprié car je ne veux généralement que do ouvrir un seul panneau à la fois.

Cependant, je dois proposer un lien "Tout développer" qui passe à "Tout réduire" lorsque vous cliquez dessus. Je ne souhaite pas personnaliser la fonctionnalité d'accordéon presque identique autour de cette seule exigence. J'aimerais donc un JS capable de le faire tout en maintenant le composant Accordion utilisé.

Question: Quel JavaScript/jQuery est requis pour y parvenir tout en utilisant toujours le composant "Accordion" de l'interface utilisateur jQuery pour alimenter les fonctionnalités standard?

Voici un violon: http://jsfiddle.net/alecrust/a6Cu7/

32
AlecRust

Finalement, j'ai trouvé que c'était la meilleure solution compte tenu des exigences:

// Expand/Collapse all
$('.accordion-expand-collapse a').click(function() {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').next().slideToggle();
    $(this).text($(this).text() == 'Expand all' ? 'Collapse all' : 'Expand all');
    $(this).toggleClass('collapse');
    return false;
});
5
AlecRust

Comme discuté dans les forums de jQuery UI, vous ne devez pas utiliser d'accordéon pour cela. 

Si vous voulez quelque chose qui ressemble à un accordéon et agit comme tel, c'est très bien. Utilisez leurs classes pour les styler et implémentez toutes les fonctionnalités dont vous avez besoin. Ajouter un bouton pour les ouvrir ou les fermer est donc très simple. Exemple

HTML

En utilisant les classes jquery-ui, nous faisons en sorte que nos accordéons ressemblent aux "vrais" accordéons.

<div id="accordion" class="ui-accordion ui-widget ui-helper-reset">
    <h3 class="accordion-header ui-accordion-header ui-helper-reset ui-state-default ui-accordion-icons ui-corner-all">
        <span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-e"></span>
        Section 1
    </h3>
    <div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom">
        Content 1
    </div>
</div>​

Roulez vos propres accordéons

La plupart du temps, nous souhaitons simplement que les en-têtes d'accordéon changent l'état du frère suivant, c'est-à-dire sa zone de contenu. Nous avons également ajouté deux événements personnalisés, "show" et "hide", auxquels nous accrocherons plus tard.

var headers = $('#accordion .accordion-header');
var contentAreas = $('#accordion .ui-accordion-content ').hide();
var expandLink = $('.accordion-expand-all');

headers.click(function() {
    var panel = $(this).next();
    var isOpen = panel.is(':visible');

    // open or close as necessary
    panel[isOpen? 'slideUp': 'slideDown']()
        // trigger the correct custom event
        .trigger(isOpen? 'hide': 'show');

    // stop the link from causing a pagescroll
    return false;
});

Développer/Réduire tout

Nous utilisons un indicateur booléen isAllOpen pour indiquer que le bouton a été modifié. Il aurait tout aussi bien pu s'agir d'une classe ou d'une variable d'état dans un cadre de plug-in plus étendu.

expandLink.click(function(){
    var isAllOpen = $(this).data('isAllOpen');

    contentAreas[isAllOpen? 'hide': 'show']()
        .trigger(isAllOpen? 'hide': 'show');
});

Echangez le bouton quand "tout est ouvert"

Grâce à nos événements "show" et "hide" personnalisés, nous avons de quoi écouter lorsque les panels changent. Le seul cas particulier est "sont-ils tous ouverts", si oui le bouton devrait être un "Réduire tout", sinon il devrait être "Développer tout".

contentAreas.on({
    // whenever we open a panel, check to see if they're all open
    // if all open, swap the button to collapser
    show: function(){
        var isAllOpen = !contentAreas.is(':hidden');   
        if(isAllOpen){
            expandLink.text('Collapse All')
                .data('isAllOpen', true);
        }
    },
    // whenever we close a panel, check to see if they're all open
    // if not all open, swap the button to expander
    hide: function(){
        var isAllOpen = !contentAreas.is(':hidden');
        if(!isAllOpen){
            expandLink.text('Expand all')
            .data('isAllOpen', false);
        } 
    }
});​

Edit for comment: Conserver "1 panneau ouvert uniquement" à moins que vous n'appuyiez sur le bouton "Tout développer" est beaucoup plus simple. Exemple

50
Sinetheta

C'est ma solution:

Travailler dans un projet réel.

   $(function () {
    $("#accordion").accordion({collapsible:true, active:false});
    $('.open').click(function () {
        $('.ui-accordion-header').removeClass('ui-corner-all').addClass('ui-accordion-header-active ui-state-active ui-corner-top').attr({'aria-selected':'true','tabindex':'0'});
        $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
        $('.ui-accordion-content').addClass('ui-accordion-content-active').attr({'aria-expanded':'true','aria-hidden':'false'}).show();
        $(this).hide();
        $('.close').show();
    });
    $('.close').click(function () {
        $('.ui-accordion-header').removeClass('ui-accordion-header-active ui-state-active ui-corner-top').addClass('ui-corner-all').attr({'aria-selected':'false','tabindex':'-1'});
        $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
        $('.ui-accordion-content').removeClass('ui-accordion-content-active').attr({'aria-expanded':'false','aria-hidden':'true'}).hide();
        $(this).hide();
        $('.open').show();
    });
    $('.ui-accordion-header').click(function () {
        $('.open').show();
        $('.close').show();
    });
});

http://jsfiddle.net/bigvax/hEApL/

18
bigvax

Beaucoup d'entre eux semblent trop compliqués. J'ai réalisé ce que je voulais avec juste ce qui suit:

$(".ui-accordion-content").show();

JSFiddle

16
Charles Clayton

Je ne crois pas que vous puissiez faire cela avec un accordéon car il a été spécialement conçu pour préserver la propriété d'ouvrir au plus un élément. Cependant, même si vous dites que vous ne voulez pas réimplémenter l'accordéon, vous pourriez peut-être surestimer la complexité impliquée. 

Considérez le scénario suivant où vous avez une pile verticale d’éléments, 

++++++++++++++++++++
+     Header 1     +
++++++++++++++++++++
+                  +
+      Item 1      +
+                  +
++++++++++++++++++++
+     Header 2     +
++++++++++++++++++++
+                  +
+      Item 2      +
+                  +
++++++++++++++++++++

Si vous êtes paresseux, vous pouvez construire ceci en utilisant une table, sinon, des DIVs convenablement stylées fonctionneront également. 

Chacun des blocs d’articles peut avoir une classe de itemBlock. En cliquant sur un en-tête, tous les éléments de la classe itemBlock seront masqués ($(".itemBlock").hide()). Vous pouvez ensuite utiliser la fonction jquery slideDown() pour développer l'élément sous l'en-tête. Maintenant que vous avez à peu près implémenté l'accordéon. 

Pour développer tous les éléments, utilisez simplement $(".itemBlock").show() ou, si vous le souhaitez, $(".itemBlock").slideDown(500). Pour masquer tous les éléments, utilisez simplement $(".itemBlock").hide().

3
PhilDin

Voici le code de Sinetheta converti en un plugin jQuery: Enregistrez le code ci-dessous dans un fichier js. 

$.fn.collapsible = function() {
    $(this).addClass("ui-accordion ui-widget ui-helper-reset");
    var headers = $(this).children("h3");
    headers.addClass("accordion-header ui-accordion-header ui-helper-reset ui-state-active ui-accordion-icons ui-corner-all");
    headers.append('<span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-s">');
    headers.click(function() {
        var header = $(this);
        var panel = $(this).next();
        var isOpen = panel.is(":visible");
        if(isOpen)  {
            panel.slideUp("fast", function() {
                panel.hide();
                header.removeClass("ui-state-active")
                    .addClass("ui-state-default")
                    .children("span").removeClass("ui-icon-triangle-1-s")
                        .addClass("ui-icon-triangle-1-e");
          });
        }
        else {
            panel.slideDown("fast", function() {
                panel.show();
                header.removeClass("ui-state-default")
                    .addClass("ui-state-active")
                    .children("span").removeClass("ui-icon-triangle-1-e")
                        .addClass("ui-icon-triangle-1-s");
          });
        }
    });
}; 

Reportez-le dans votre page d'interface utilisateur et appelez de la même manière qu'un appel accordéian jQuery: 

$("#accordion").collapsible(); 

A l'air plus propre et évite l'ajout de classes au balisage.

2
Ullas Antony

essayez celui-ci jquery-multi-open-accordéon , pourrait vous aider

1
rajesh kakawat

J'ai déjà commenté bigvax plus tôt, mais vous devez vous assurer que vous ajoutez 

        jQuery("#jQueryUIAccordion").({ active: false,
                              collapsible: true });

sinon vous ne pourrez pas ouvrir le premier accordéon après les avoir effondrés. 

    $('.close').click(function () {
    $('.ui-accordion-header').removeClass('ui-accordion-header-active ui-state-active ui-corner-top').addClass('ui-corner-all').attr({'aria-selected':'false','tabindex':'-1'});
    $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
    $('.ui-accordion-content').removeClass('ui-accordion-content-active').attr({'aria-expanded':'false','aria-hidden':'true'}).hide();
   }
1
craig_nelson

J'ai trouvé la solution d'AlecRust très utile, mais j'ai ajouté quelque chose pour résoudre un problème: lorsque vous cliquez sur un seul accordéon pour le développer, puis sur le bouton pour le développer, ils seront tous ouverts. Mais, si vous cliquez à nouveau sur le bouton pour le réduire, l’accordéon simple ne se développera pas avant.

J'ai utilisé imageButton, mais vous pouvez également appliquer cette logique aux boutons.

/*** Expand all ***/
$(".expandAll").click(function (event) {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').next().slideDown();

    return false;
});

/*** Collapse all ***/
$(".collapseAll").click(function (event) {
    $('.accordion').accordion({
        collapsible: true,
        active: false
    });

    $('.accordion .ui-accordion-header').next().slideUp();

    return false;
});

De plus, si vous avez des accordéons à l'intérieur d'un accordéon et que vous souhaitez tout développer uniquement à ce deuxième niveau, vous pouvez ajouter une requête:

/*** Expand all Second Level ***/
$(".expandAll").click(function (event) {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').nextAll(':has(.accordion .ui-accordion-header)').slideDown();

    return false;
});
0
Freelex

En utilisant un exemple sur Taifun, J'ai modifié pour permettre l'expansion et l'effondrement.

... // brancher le tout développer/réduire

var expandLink = $('.accordion-expand-all');

expandLink.click(function () {

$(".ui-accordion-content").toggle();
});
0
NCR

Vous pouvez essayer ce petit plugin léger.

Cela vous permettra de le personnaliser selon vos besoins. Il aura la fonctionnalité Développer/Réduire.

URL: _ ​​http://accordion-cd.blogspot.com/

0
Dharam Mali
Yes, it is possible. Put all div in separate accordion class as follows:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>

<script type="text/javascript">

        $(function () {
            $("input[type=submit], button")
        .button()
        .click(function (event) {
            event.preventDefault();
        });
            $("#tabs").tabs();
            $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: 0



            });
        });

function expandAll()
{
  $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: 0

            });

            return false;   
}

function collapseAll()
{
  $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: false



            });
            return false;
}
</script>



<div class="accordion">
  <h3>Toggle 1</h3>
  <div >
    <p>text1.</p>
  </div>
</div>
<div class="accordion">
  <h3>Toggle 2</h3>
  <div >
    <p>text2.</p>
  </div>
</div>
<div class="accordion">
  <h3>Toggle 3</h3>
  <div >
    <p>text3.</p>
  </div>
</div>
0
Manish Ojha