Ajout d'une icône ouverte / fermée aux collapsibles Twitter Bootstrap (accordéons)

87

J'ai mis en place cette version simple de l' accordéon Bootstrap :

Accordéon simple: http://jsfiddle.net/darrenc/cngPS/

Actuellement, l'icône ne pointe que vers le bas , mais est-ce que quelqu'un sait quel JS serait nécessaire pour être implémenté afin de changer la classe de l'icône en:

<i class="icon-chevron-up"></i>

... de sorte qu'il pointe jusqu'à quand étendus et dos à bascule vers le bas à nouveau quand il est replié, et ainsi de quatrième?

Darren
la source

Réponses:

94

Voici la réponse pour ceux qui recherchent une solution dans Bootstrap 3 (comme moi).

La partie HTML:

<div class="btn-group">
  <button type="button" class="btn btn-danger">Action</button>
  <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#demo">
    <span class="glyphicon glyphicon-minus"></span>
  </button>
</div>
<div id="demo" class="collapse in">Some dummy text in here.</div>

La partie js:

$('.collapse').on('shown.bs.collapse', function(){
$(this).parent().find(".glyphicon-plus").removeClass("glyphicon-plus").addClass("glyphicon-minus");
}).on('hidden.bs.collapse', function(){
$(this).parent().find(".glyphicon-minus").removeClass("glyphicon-minus").addClass("glyphicon-plus");
});

Exemple d'accordéon:

Exemple d'accordéon Bootply

Andrei Veve
la source
6
exactement ce qui est nécessaire pour bootstrap 3.x. si vous utilisez 2.x remove .bs.collapse. J'ai également changé shown and hidden to show and hidepour que l'animation se produise avant l'ouverture de l'accordéon.
user1881482
2
cela devrait être la bonne réponse car il fonctionne également en version 4
Andres Felipe
Et pour les accordéons imbriqués? les éléments enfants n'ont pas de chevrons mais j'obtiens toujours le commutateur sur le parent.
ésotérique
48

Voici mon approche pour Bootstrap 2.x. C'est juste du CSS. Aucun JavaScript nécessaire:

    .accordion-caret .accordion-toggle:hover {
        text-decoration: none;
    }
    .accordion-caret .accordion-toggle:hover span,
    .accordion-caret .accordion-toggle:hover strong {
        text-decoration: underline;
    }
    .accordion-caret .accordion-toggle:before {
        font-size: 25px;
        vertical-align: -3px;
    }
    .accordion-caret .accordion-toggle:not(.collapsed):before {
        content: "▾";
        margin-right: 0px;
    }
    .accordion-caret .accordion-toggle.collapsed:before {
        content: "▸";
        margin-right: 0px;
    }

Ajoutez simplement la classe accordéon-caret à la div du groupe d'accordéon, comme ceci:

<div class="accordion-group accordion-caret">
    <div class="accordion-heading">
        <a class="accordion-toggle" data-toggle="collapse" href="#collapseOne">
            <strong>Header</strong>
        </a>
    </div>
    <div id="collapseOne" class="accordion-body collapse in">
        <div class="accordion-inner">
            Content
        </div>
    </div>
</div>
Martin Wickman
la source
2
J'ai beaucoup aimé cette approche Martin. Surtout parce que c'est très discret.
J Castillo
4
J'ai trouvé que cela fonctionnait à une exception près: le curseur initial est toujours développé pour toutes les sections. Une fois que vous développez puis réduisez à nouveau, c'est correct.
Robb Sadler
8
@Robb - J'ai inclus la classe "collapsed" sur mon élément "collapse" dans le html pour résoudre le problème avec la flèche initiale. Mon html est un peu différent mais ça marchera probablement
Mark B
1
J'aime aussi la solution css. Certains de mes pairs sont plus à l'aise en css qu'en javascript, c'était donc une meilleure solution pour mon équipe. Merci d'avoir abordé la partie d'initialisation. Maintenant, cela fonctionne très bien!
Hcabnettek
42

Le Bootstrap Collapse a des événements auxquels vous pouvez réagir:

$(document).ready(function(){    
    $('#accordProfile').on('shown', function () {
       $(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-up");
    });

    $('#accordProfile').on('hidden', function () {
       $(".icon-chevron-up").removeClass("icon-chevron-up").addClass("icon-chevron-down");
    });
});
Philipp Hofmann
la source
1
Muffls, vous êtes une star! gentil et simple aussi, merci pour ça ;-)
Darren
1
de rien! vous pouvez également utiliser afficher ou masquer au lieu d'afficher et de masquer. Essaye le. Vous verrez celui que vous préférez.
Philipp Hofmann
1
Salut Muffs, une idée pourquoi cela ne fonctionnera pas sur mon site de test en direct? datascrew.co.uk/gordonedge.com
Darren
ajouter $ (document) .ready (... dans votre main.js j'ai mis le code ci-dessus.
Philipp Hofmann
8
Bootstrap3: les noms d'événements doivent avoir .bs.collapse, ils sont donc activés ('hide.bs.collapse') et activés ('show.bs.collapse'), ou affichés / masqués lorsque vous souhaitez ajouter plus de transitions css à il.
Langeleppel
21

Utilisez le pseudo-sélecteur CSSes: après avoir utilisé les Glyphicons intégrés de Bootstrap 3 pour une réponse non JS avec une modification mineure de votre HTML ...

CSS

.panel-heading [data-toggle="collapse"]:after
{
    font-family: 'Glyphicons Halflings';
    content: "\e072"; /* "play" icon */
    float: right;
    color: #b0c5d8;
    font-size: 18px;
    line-height: 22px;

    /* rotate "play" icon from > (right arrow) to down arrow */
    -webkit-transform: rotate(-90deg);
    -moz-transform:    rotate(-90deg);
    -ms-transform:     rotate(-90deg);
    -o-transform:      rotate(-90deg);
    transform:         rotate(-90deg);
}
.panel-heading [data-toggle="collapse"].collapsed:after
{
    /* rotate "play" icon from > (right arrow) to ^ (up arrow) */
    -webkit-transform: rotate(90deg);
    -moz-transform:    rotate(90deg);
    -ms-transform:     rotate(90deg);
    -o-transform:      rotate(90deg);
    transform:         rotate(90deg);
}

HTML

Ajoutez class="collapsed"à toutes les balises d'ancrage fermées par défaut.

Cela fera tourner les ancres telles que

<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">

dans

<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">

Exemple CodePen Live

http://codepen.io/anon/pen/VYobER

Capture d'écran

Comment cela apparaît dans JSBin

bafromca
la source
1
ce lien jsbin a été signalé
Nick Bartlett
2
Je l'ai déplacé vers CodePen. Merci d'avoir signalé. Essaie!
bafromca
16

Ajouté à @muffls answer pour que cela fonctionne avec tous les collapsus de bootstrap de Twitter et modifie la flèche avant le début de l'animation.

$('.collapse').on('show', function(){
    $(this).parent().find(".icon-chevron-left").removeClass("icon-chevron-left").addClass("icon-chevron-down");
}).on('hide', function(){
    $(this).parent().find(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-left");
});

En fonction de votre structure HTML, vous devrez peut-être modifier le fichier parent().

John Magnolia
la source
1
+1 l'a déposé et cela a fonctionné pour moi - juste modifié pour utiliser l'icône-chevron-droite au lieu de gauche
azcoastal
1
Celui-ci fonctionne pour moi. Les autres codes changent de classe pour tous les onglets lorsque vous cliquez dessus au lieu de l'onglet cliqué :)
vignesh
10

Je pense que les meilleurs codes sont les suivants:

  $('#accordion1').collapse({
    toggle: false
  }).on('show',function (e) {
        $(e.target).parent().find(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-up");
      }).on('hide', function (e) {
        $(e.target).parent().find(".icon-chevron-up").removeClass("icon-chevron-up").addClass("icon-chevron-down");
      });
user2273425
la source
2
C'est la seule solution de travail pour moi, reste basculer la classe de tous les groupes d'accordéon. Cheers :)
maximus ツ
6

Si quelqu'un est intéressé, voici comment vous faites avec BS3 depuis qu'ils ont changé les noms des événements:

$('.collapse').on('show.bs.collapse', function(){
  var i = $(this).parent().find('i')
  i.toggleClass('fa-caret-right fa-caret-down');
}).on('hide.bs.collapse', function(){
  var i = $(this).parent().find('i')
  i.toggleClass('fa-caret-down fa-caret-right');
});

Vous changez simplement les noms de classe dans l'exemple pour ceux que vous utilisez dans votre cas.

rbsthlm
la source
1
Merci b3rgstrom, apprécié. Je vérifierai cela lors de ma prochaine utilisation de BS3.
Darren
1
Aucun problème, je pensais que quelqu'un pourrait trouver votre question à l'avenir avec le même problème :)
rbsthlm
5

La solution CSS uniquement la plus lisible serait probablement d'utiliser l'attribut aria-extended. N'oubliez pas que vous devrez ajouter aria-Expand = "false" à tous les éléments de réduction car cela n'est pas défini au chargement (uniquement au premier clic).

Le HTML:

<h2 data-toggle="collapse" href="#collapseId" aria-expanded="false">
    <span class="glyphicon glyphicon-chevron-right"></span>
    <span class="glyphicon glyphicon-chevron-down"></span> Title
</h2>

Le CSS:

h2[aria-expanded="false"] span.glyphicon-chevron-down,
h2[aria-expanded="true"] span.glyphicon-chevron-right
{
    display: none;
}

h2[aria-expanded="true"] span.glyphicon-chevron-down,
h2[aria-expanded="false"] span.glyphicon-chevron-right
{
    display: inline;
}

Fonctionne avec Bootstrap 3.x.

Andreas Bergström
la source
1
Cela fonctionne parfaitement. Parce que ma balise d'ancrage était le
basculement
3

Voici ma solution qui est affinée à partir de celle publiée par @ john-magnolia et résout certains de ses problèmes

/**
 * Toggle on/off arrow for Twitter Bootstrap collapsibles.
 *
 * Multi-collapsible-friendly; supports several collapsibles in the same group, on the same page.
 */
function animateCollapsibles() {

    $('.collapse').on('show', function() {
        var $t = $(this);
        var header = $("a[href='#" + $t.attr("id") + "']");
        header.find(".icon-chevron-right").removeClass("icon-chevron-right").addClass("icon-chevron-down");
    }).on('hide', function(){
        var $t = $(this);
        var header = $("a[href='#" + $t.attr("id") + "']");
        header.find(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-right");
    });
}

Et voici l'exemple de balisage:

<div class="accordion" id="accordion-send">
    <div class="accordion-group">
        <div class="accordion-heading">
            <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion-send" href="#collapse-refund">
                <i class="icon icon-chevron-right"></i> Send notice
            </a>
        </div>
        <div id="collapse-refund" class="accordion-body collapse">
            <div class="accordion-inner">
                <p>Lorem ipsum Toholampi city</p>
            </div>
        </div>
    </div>
</div>
Mikko Ohtamaa
la source
1
Bonnes gens - je me sens le grand idiot, mais je ne peux faire fonctionner aucune de ces solutions: -S la seule différence à laquelle je pense est que j'utilise le nouveau bootstrap3, et donc j'obtiens les classes "glyphicon glyphicon-chevron-right. pointeurs?
benteh
2
Bootstrap 3 n'est pas une version rétrocompatible. Veuillez consulter la documentation Bootstrap 3 pour savoir comment migrer le code.
Mikko Ohtamaa
1
Bonjour, Mikko, merci, oui j'ai rassemblé cela et j'ai obtenu une bonne aide ici: stackoverflow.com/questions/18147338
...
3

Une solution bootstrap v3 (où les événements ont des noms différents), utilisant également un seul sélecteur jQuery (comme vu ici ):

$('.accordion').on('hide.bs.collapse show.bs.collapse', function (n) {
    $(n.target).siblings('.panel-heading').find('i.glyphicon').toggleClass('glyphicon-chevron-down glyphicon-chevron-up');
});
Geert
la source
Excellente réponse
Naveen DA
3

C'est comme ça que je le fais sans aucun js.

J'ai utilisé l'icône glyphicon-triangle-right mais cela fonctionne avec n'importe quelle autre icône, ce qu'il fait, c'est qu'il applique une rotation de 90 degrés à l'icône lorsque le panneau est ouvert ou non. J'utilise Bootstrap 3.3.5 pour celui-ci.

Code CSS

h4.panel-title a {
    display: block;

}
h4.panel-title a.collapsed .glyphicon-triangle-right {
        color: #ada9a9 !important;
        transform: rotate(0deg);
}
h4.panel-title a .glyphicon-triangle-right {
        color: #515e64 !important;
        transform: rotate(90deg);
}

Il s'agit de la structure HTML tirée de l'exemple Bootstrap

<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
                            <div class="panel panel-default">
                                <div class="panel-heading" role="tab" id="headingOne">
                                    <h4 class="panel-title">
                                        <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                                            Proven Expertise
                                            <span class="glyphicon glyphicon-triangle-right pull-right" aria-hidden="true"></span>
                                        </a>
                                    </h4>
                                </div>
                                <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
                                    <div class="panel-body">
                                        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
                                    </div>
                                </div>
                            </div>

                        </div>
General Electric
la source
Cette méthode fonctionne pour moi, mais l'état initial est tourné de 90 degrés. Pourriez-vous suggérer avec bonté comment rendre le statut initial non pivoté (0deg)? Merci!
Tsung-Ting Kuo
1
Dans les éléments d'ancrage, ajoutez le class = "collapsed" pour éviter ce qui vous arrive
General Electric
Merci pour la réponse! J'ai en fait essayé '<h4 class = "panel-title collapsed">' mais je n'ai pas eu de chance. Serait-ce correct?
Tsung-Ting Kuo
1
Cela doit être sur la balise d'ancrage car c'est ce que bootstrap js change lorsque l'événement onClick se déclenche, vérifiez sur cette page, fonctionne avec la solution que j'ai mentionnée acubavoy.com/preguntas-frequentes
General Electric
2

Aucune de ces solutions n'a fonctionné pour moi, mais j'ai trouvé ceci et cela a fonctionné:

function toggleChevron(el) {
  if ($(el).find('i').hasClass('icon-chevron-left'))
      $(el).find('.icon-chevron-left').removeClass("icon-chevron-left").addClass("icon-chevron-down");
  else 
      $(el).find('.icon-chevron-down').removeClass("icon-chevron-down").addClass("icon-chevron-left");
}

Implémentation HTML:

<div class="accordion" id="accordion-send">
  <div class="accordion-group">
    <div class="accordion-heading" onClick="toggleChevron(this)">
      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion-send" href="#collapse-refund">
        <i class="icon icon-chevron-right"></i> Send notice
      </a>
      ...
Joshua Benson
la source
1

@RobSadler:

Version CSS uniquement de RE Martin Wickman ...

Vous pouvez contourner ce problème en mettant accordéon-caret sur la balise d'ancrage et en lui donnant une classe réduite par défaut. Ainsi:

<div class="accordion-group">
<div class="accordion-heading">
    <a class="accordion-toggle accordion-caret collapsed" data-toggle="collapse" href="#collapseOne">
        <strong>Header</strong>
    </a>
</div>
<div id="collapseOne" class="accordion-body collapse in">
    <div class="accordion-inner">
        Content
    </div>
</div>

Cela a fonctionné pour moi.

RioBrewster
la source
1

Pour Bootstrup 3.2 + FontAwesome

$(document).ready(function(){    
    $('#accordProfile').on('shown.bs.collapse', function () {
       $(".fa-chevron-down").removeClass("fa-chevron-down").addClass("fa-chevron-up");
    });

    $('#accordProfile').on('hidden.bs.collapse', function () {
       $(".fa-chevron-up").removeClass("fa-chevron-up").addClass("fa-chevron-down");
    });
});

Parfois, vous devez l'écrire. Si c'est le cas

$('.collapsed span').removeClass('fa-minus').addClass('fa-plus');

Généré automatiquement (class = "collapsed"), lorsque vous appuyez sur le menu Masquer.

ps lorsque vous devez créer un menu arborescent

Popov Andrey
la source
1

Cela a été répondu de nombreuses façons, mais ce que j'ai trouvé était le plus simple et le plus facile pour moi avec Bootstrap 3 et la police géniale. je viens de faire

$('a.toggler').on('click', function () {$('i', this).toggleClass('fa-caret-up');});

Cela bascule simplement la classe CSS de l'icône que je veux afficher. J'ajoute le basculeur de classe à l'élément auquel je souhaite l'appliquer. Cela peut être ajouté à n'importe quel élément pour lequel vous souhaitez basculer une icône.

Micah Montoya
la source
0

Une autre solution sans javascript qui utilise la fonctionnalité de réduction elle-même:

/* Prevent block display and transition animation */
.expand-icon.collapse.in,
.collapse-icon.collapse.in {
  display: inline; }
.expand-icon.collapsing {
  display: none; }

/* HTML Toggler with glyphicons */
<a data-toggle="collapse" href=".my-collapse">
 <span class="my-collapse collapse-icon collapse in">
  <span class="glyphicon glyphicon-collapse-up"></span>
 </span>
 <span class="my-collapse expand-icon collapse">
  <span class="glyphicon glyphicon-expand"></span>   
 </span>
</a>
Sebastian Sangervasi
la source
0

Pour une solution CSS uniquement (et sans icône) utilisant Bootstrap 3, j'ai dû faire un peu de violon basé sur la réponse de Martin Wickman ci-dessus.

Je n'ai pas utilisé la notation accordéon- * car c'est fait avec des panneaux dans BS3.

De plus, j'ai dû inclure dans le code HTML initial aria-extended = "true" sur l'élément qui est ouvert au chargement de la page.

Voici le CSS que j'ai utilisé.

.accordion-toggle:hover { text-decoration: none; }
.accordion-toggle:hover span, .accordion-toggle:hover strong { text-decoration: underline; }
.accordion-toggle:before { font-size: 25px; }
.accordion-toggle[data-toggle="collapse"]:before { content: "+"; margin-right: 0px; }
.accordion-toggle[aria-expanded="true"]:before { content: "-"; margin-right: 0px; }

Voici mon HTML purifié:

<div id="acc1">    
    <div class="panel panel-default">
        <div class="panel-heading">
            <span class="panel-title">
                <a class="accordion-toggle" data-toggle="collapse" aria-expanded="true" data-parent="#acc1" href="#acc1-1">Title 1
                    </a>
            </span>
        </div>
        <div id=“acc1-1” class="panel-collapse collapse in">
            <div class="panel-body">
                Text 1
            </div>
        </div>
    </div>
    <div class="panel panel-default">
        <div class="panel-heading">
            <span class="panel-title">
                <a class="accordion-toggle" data-toggle="collapse" data-parent="#acc1” href=“#acc1-2”>Title 2
                    </a>
            </span>
        </div>
        <div id=“acc1-2” class="panel-collapse collapse">
            <div class="panel-body">
                Text 2                  
            </div>
        </div>
    </div>
</div>
JessycaFrederick
la source
0

Réponse la plus courte possible.

HTML

<a data-toggle="collapse" data-parent="#panel-quote-group" href="#collapseQuote">
    <span class="toggle-icon glyphicon glyphicon-collapse-up"></span>
</a>

JS:

<script type="text/javascript">
 $(function () {
     $('a[data-toggle="collapse"]').click(function () {
     $(this).find('span.toggle-icon').toggleClass('glyphicon-collapse-up glyphicon-collapse-down');
     })
 })
 </script>

Et bien sûr, vous pouvez utiliser n'importe quoi pour un sélecteur au lieu d'une balise d'ancrage aet vous pouvez également utiliser un sélecteur spécifique au lieu de savoir thissi votre icône se trouve en dehors de l'élément sur lequel vous avez cliqué.

Junaid
la source
0

Voici une solution qui crée une section extensible en utilisant une conception quelque peu matérielle, bootstrap 4.5 / 5 alpha et entièrement non-javascript.

Style pour la section de tête

<style>
[data-toggle="collapse"] .fa:before {
    content: "\f077";
}

[data-toggle="collapse"].collapsed .fa:before {
    content: "\f078";
}
</style>

Corps html

<div class="pt-3 pb-3" style="border-top: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; cursor: pointer;">
<a href="#expandId" class="text-dark float-right collapsed" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="expandId">
    <i class="fa" aria-hidden="false"></i>
</a>
<a href="#expandId" class="text-dark collapsed" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="expandId">Expand Header</a>
<div class="collapse" id="expandId">
    CONTENT GOES IN HERE
</div>
William Worley
la source