Menu déroulant à plusieurs niveaux de Twitter Bootstrap

89

Est-il possible d'avoir un menu déroulant à plusieurs niveaux en utilisant les éléments de Twitter Bootstrap 2? La version originale n'a pas cette fonctionnalité.

Hellnar
la source
effectivement cherché une implémentation mais je n'ai pas eu de chance avec elle.
Hellnar
Peut-être avez-vous besoin d'un menu de poisson-suceur? htmldog.com/articles/suckerfish/dropdowns
Elaine Marley
1
jetez un œil à ceci aussi: github.com/twitter/bootstrap/issues/424
Paolo

Réponses:

113

Réponse mise à jour

* Réponse mise à jour prenant en charge la feuille de style de la version bootstrap v2.1.1 **.

** Mais attention car cette solution a été supprimée de la v3

Je voulais juste souligner que cette solution n'est plus nécessaire car le dernier bootstrap prend désormais en charge les listes déroulantes à plusieurs niveaux par défaut. Vous pouvez toujours l'utiliser si vous utilisez des versions plus anciennes, mais pour ceux qui ont mis à jour vers la dernière (v2.1.1 au moment de la rédaction), ce n'est plus nécessaire. Voici un violon avec la liste déroulante à plusieurs niveaux par défaut mise à jour directement à partir de la documentation:

http://jsfiddle.net/2Smgv/2858/


Réponse originale

Des problèmes ont été soulevés concernant la prise en charge des sous-menus sur github et ils sont généralement fermés par les développeurs de bootstrap, comme celui-ci , donc je pense que c'est aux développeurs qui utilisent le bootstrap de trouver quelque chose. Voici une démo que j'ai préparée pour vous montrer comment pirater un sous-menu fonctionnel.

Code pertinent

CSS

.dropdown-menu .sub-menu {
    left: 100%;
    position: absolute;
    top: 0;
    visibility: hidden;
    margin-top: -1px;
}

.dropdown-menu li:hover .sub-menu {
    visibility: visible;
    display: block;
}

.navbar .sub-menu:before {
    border-bottom: 7px solid transparent;
    border-left: none;
    border-right: 7px solid rgba(0, 0, 0, 0.2);
    border-top: 7px solid transparent;
    left: -7px;
    top: 10px;
}
.navbar .sub-menu:after {
    border-top: 6px solid transparent;
    border-left: none;
    border-right: 6px solid #fff;
    border-bottom: 6px solid transparent;
    left: 10px;
    top: 11px;
    left: -6px;
}

J'ai créé ma propre .sub-menuclasse à appliquer aux menus déroulants à 2 niveaux, de cette façon nous pouvons les positionner à côté de nos éléments de menu. Également modifié la flèche pour l'afficher à gauche du groupe de sous-menus.

Démo

Andres Ilich
la source
2
Depuis un Bootstrap 2.0.4, vous devez également avoir la déclaration "display: block;" dans le sélecteur ".dropdown-menu li: hover .sub-menu".
Omar le
J'ai essayé de l'implémenter, le premier sous-menu fonctionne très bien. Mais si j'ajoute un autre sous-menu dans le même menu, alors les choses tournent mal. Pour une raison quelconque, il ouvre le premier sous-menu au lieu du second. Toute idée ou indice serait le bienvenu. Déjà thankx :)
Arjan
Hermes - Voir ma réponse pour savoir comment réparer le blocage du sous-menu.
Sean Lynch
1
@Kannika mobiliser ce correctif nécessiterait un balisage supplémentaire et probablement également du javascript. Je suggère simplement d'afficher le contenu de la liste déroulante de deuxième niveau au lieu de le cacher sur les appareils mobiles afin de garder les choses propres. J'essaierai de travailler sur une solution plus tard dans la journée. Cependant, je n'ai pas testé la solution de bootstrap par défaut, donc vous pouvez toujours y aller.
Andres Ilich
5
La version mise à jour ne fonctionne qu'avec Bootstrap 2.3.2, elle a été supprimée dans Bootstrap 3.0
seantomburke
34

[Twitter Bootstrap v3]

Pour créer un menu déroulant à n niveaux (compatible avec les appareils tactiles) dans Twitter Bootstrap v3,

CSS:

.dropdown-menu>li /* To prevent selection of text */
{   position:relative;
    -webkit-user-select: none; /* Chrome/Safari */        
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+ */
    /* Rules below not implemented in browsers yet */
    -o-user-select: none;
    user-select: none;
    cursor:pointer;
}
.dropdown-menu .sub-menu 
{
    left: 100%;
    position: absolute;
    top: 0;
    display:none;
    margin-top: -1px;
    border-top-left-radius:0;
    border-bottom-left-radius:0;
    border-left-color:#fff;
    box-shadow:none;
}
.right-caret:after,.left-caret:after
 {  content:"";
    border-bottom: 5px solid transparent;
    border-top: 5px solid transparent;
    display: inline-block;
    height: 0;
    vertical-align: middle;
    width: 0;
    margin-left:5px;
}
.right-caret:after
{   border-left: 5px solid #ffaf46;
}
.left-caret:after
{   border-right: 5px solid #ffaf46;
}

JQuery:

$(function(){
    $(".dropdown-menu > li > a.trigger").on("click",function(e){
        var current=$(this).next();
        var grandparent=$(this).parent().parent();
        if($(this).hasClass('left-caret')||$(this).hasClass('right-caret'))
            $(this).toggleClass('right-caret left-caret');
        grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');
        grandparent.find(".sub-menu:visible").not(current).hide();
        current.toggle();
        e.stopPropagation();
    });
    $(".dropdown-menu > li > a:not(.trigger)").on("click",function(){
        var root=$(this).closest('.dropdown');
        root.find('.left-caret').toggleClass('right-caret left-caret');
        root.find('.sub-menu:visible').hide();
    });
});

HTML:

<div class="dropdown" style="position:relative">
    <a href="#" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">Click Here <span class="caret"></span></a>
    <ul class="dropdown-menu">
        <li>
            <a class="trigger right-caret">Level 1</a>
            <ul class="dropdown-menu sub-menu">
                <li><a href="#">Level 2</a></li>
                <li>
                    <a class="trigger right-caret">Level 2</a>
                    <ul class="dropdown-menu sub-menu">
                        <li><a href="#">Level 3</a></li>
                        <li><a href="#">Level 3</a></li>
                        <li>
                            <a class="trigger right-caret">Level 3</a>
                            <ul class="dropdown-menu sub-menu">
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li><a href="#">Level 2</a></li>
            </ul>
        </li>
        <li><a href="#">Level 1</a></li>
        <li><a href="#">Level 1</a></li>
    </ul>
</div>
Chirayu Chiripal
la source
Malheureusement, cela n'affiche pas le menu lorsque le bouton «réduit» du menu s'affiche. Dans Chrome et FF.
Ben Power
@BenPower Pouvez-vous s'il vous plaît fournir une démo jsfiddle de celui-ci, afin que je puisse l'examiner parce que la démo jsfiddle que j'ai donnée fonctionne bien. Quelles versions de Bootstrap, JQuery et navigateurs Web utilisez-vous également?
Chirayu Chiripal
Cela fonctionne pour Bootstrap v3.0. Buddy ... Pourriez-vous s'il vous plaît le rendre compatible avec Bootstrap v2.3.2?
Niks Jain
1
J'ai ajouté trigger.off('click');avant de paramétrer les écouteurs afin d'éviter la "double écoute" d'un événement au cas où l'initialisation javascript serait déclenchée plus d'une fois.
FranBran
1
L'inversion du curseur a ajouté plusieurs lignes de code et n'est pas nécessaire.
Ruben
23

Cet exemple provient de http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3

Fonctionne pour moi dans Bootstrap v3.1.1.

HTML

<div class="container">
<div class="row">
    <h2>Multi level dropdown menu in Bootstrap 3</h2>
    <hr>
    <div class="dropdown">
        <a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" data-target="#" href="/page.html">
            Dropdown <span class="caret"></span>
        </a>
        <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
          <li><a href="#">Some action</a></li>
          <li><a href="#">Some other action</a></li>
          <li class="divider"></li>
          <li class="dropdown-submenu">
            <a tabindex="-1" href="#">Hover me for more options</a>
            <ul class="dropdown-menu">
              <li><a tabindex="-1" href="#">Second level</a></li>
              <li class="dropdown-submenu">
                <a href="#">Even More..</a>
                <ul class="dropdown-menu">
                    <li><a href="#">3rd level</a></li>
                    <li><a href="#">3rd level</a></li>
                </ul>
              </li>
              <li><a href="#">Second level</a></li>
              <li><a href="#">Second level</a></li>
            </ul>
          </li>
        </ul>
    </div>
</div>

CSS

.dropdown-submenu {
position: relative;
}

.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px;
border-radius: 0 6px 6px 6px;
}

.dropdown-submenu:hover>.dropdown-menu {
display: block;
}

.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #ccc;
margin-top: 5px;
margin-right: -10px;
}

.dropdown-submenu:hover>a:after {
border-left-color: #fff;
}

.dropdown-submenu.pull-left {
float: none;
}

.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}
fandasson
la source
Merci ! la version 3.0 ne supporte plus la réponse validée
Asenar
13

J'ai pu corriger le sous-menu toujours épinglé en haut du menu parent à partir de la réponse d'Andres avec l'ajout suivant:

.dropdown-menu li {
    position: relative;
}

J'ajoute également une icône "icon-chevron-right" sur les éléments qui contiennent des sous-menus de menu, et change l'icône du noir au blanc en survol (pour compléter le texte en passant au blanc et mieux paraître avec le fond bleu sélectionné).

Voici le changement complet de less / css (remplacez ce qui précède par ceci):

.dropdown-menu li {
    position: relative;

    [class^="icon-"] {
        float: right;
    }

    &:hover {
        // Switch to white icons on hover
        [class^="icon-"] {
            background-image: url("../img/glyphicons-halflings-white.png");
        }
    }
}
Sean Lynch
la source
4

Je viens d'ajouter class="span2"aux <li>éléments de liste déroulante et cela a fonctionné.

PAR EXEMPLE
la source
3

Puisque Bootstrap 3 a supprimé la partie sous-menu et que nous devons nous adapter le style, je pense qu'il est préférable d'utiliser SmartMenu Bootstrap: https://vadikom.github.io/smartmenus/src/demo/bootstrap-navbar.html#

Cela nous ferait gagner du temps sur la réactivité et le style mobiles.

Ce plugin également très prometteur.

Osify
la source
Quelle est votre opinion sur github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover ? Je ne peux pas décider.
Csaba Toth
1
@CsabaToth, celui-ci était également à mon avis, si vous ne voulez avoir que l'API javascript bootstrap, vous pouvez utiliser celui-ci, assez léger pour être ajouté et vous pouvez vous familiariser avec les compétences générales de bootstrap si vous avez besoin de personnaliser.
Osify
Enfin, je vais utiliser l'un d'eux dans un projet et l'autre dans un site compagnon. Chaque solution correspond mieux à l'une d'entre elles
Csaba Toth