Gardez la liste déroulante Bootstrap ouverte au clic

85

J'utilise une liste déroulante bootstrap comme panier d'achat. Dans le panier se trouve un bouton «Supprimer le produit» (un lien). Si je clique dessus, mon script de panier supprime le produit, mais le menu disparaît. Y a-t-il un moyen d'éviter cela? J'ai essayé e.startPropagation, mais cela ne semble pas fonctionner:

<div id="shoppingcart" class="nav-collapse cart-collapse">
 <ul class="nav pull-right">
  <li class="dropdown open">
    <a href="#" data-toggle="dropdown" class="dropdown-toggle">Totaal:
    &acirc;&sbquo;&not; 43,00</a>

    <ul class="dropdown-menu">
      <li class="nav-header">Pakketten</li>

      <li>
       <span class="quantity">1x</span>
       <span class="product-name">Test Product </span>
       <span class="product-remove"><a class="removefromcart" packageid="4" href="#">x</a>
        </span></li>

      <li><a href="#">Total: &euro; 43,00</a></li>

      <li><a href="/checkout">Checkout</a></li>
    </ul>
  </li>
</ul>

Comme vous pouvez le voir, l'élément avec class = "dropwdown-toggle" en a fait une liste déroulante. Une autre idée était que je viens de le rouvrir en cliquant par programme. Donc, si quelqu'un peut m'expliquer comment ouvrir par programme une liste déroulante Bootstrap, cela aiderait bien!

Martre Sytema
la source
1
Je vois que vous avez déjà une réponse, mais il existe un moyen beaucoup plus simple. Enveloppez simplement le contenu du menu dans une balise de formulaire. C'est ça. Alors, au lieu de ul.dropdown-menu, utilisez form.dropdown-menu>ul.
rdumont

Réponses:

100

Essayez de supprimer la propagation sur le bouton lui-même comme ceci:

$('.dropdown-menu a.removefromcart').click(function(e) {
    e.stopPropagation();
});

Éditer

Voici une démo des commentaires avec la solution ci-dessus:

http://jsfiddle.net/andresilich/E9mpu/

Code pertinent:

JS

$(".removefromcart").on("click", function(e){
    var fadeDelete = $(this).parents('.product');
    $(fadeDelete).fadeOut(function() {
        $(this).remove();
    });

    e.stopPropagation();
});

HTML

<div id="shoppingcart" class="nav-collapse cart-collapse">
 <ul class="nav pull-right">
  <li class="dropdown open">
    <a href="#" data-toggle="dropdown" class="dropdown-toggle">Totaal:
    &acirc;&sbquo;&not; 43,00</a>

    <ul class="dropdown-menu">
      <li class="nav-header">Pakketten</li>
        <li class="product">
            <span class="product-remove"><a class="removefromcart" packageid="2" href="#"><i class="icon-remove"></i></a></span>
            <span class="product-name">Test Product </span>
            <span class="quantity"><span class="badge badge-inverse">1</span></span>
        </li>
        <li class="product">
            <span class="product-remove"><a class="removefromcart" packageid="2" href="#"><i class="icon-remove"></i></a></span>
            <span class="product-name">Test Product </span>
            <span class="quantity"><span class="badge badge-inverse">10</span></span>
        </li>
        <li class="product">
            <span class="product-remove"><a class="removefromcart" packageid="2" href="#"><i class="icon-remove"></i></a></span>
            <span class="product-name">Test Product </span>
            <span class="quantity"><span class="badge badge-inverse">8</span></span>
        </li>
        <li class="product">
            <span class="product-remove"><a class="removefromcart" packageid="2" href="#"><i class="icon-remove"></i></a></span>
            <span class="product-name">Test Product </span>
            <span class="quantity"><span class="badge badge-inverse">3</span></span>
        </li>
        <li class="product">
            <span class="product-remove"><a class="removefromcart" packageid="2" href="#"><i class="icon-remove"></i></a></span>
            <span class="product-name">Test Product </span>
            <span class="quantity"><span class="badge badge-inverse">4</span></span>
        </li>
        <li class="divider"></li>
        <li><a href="#">Total: &euro; 43,00</a></li>
        <li><a href="/checkout">Checkout</a></li>
    </ul>
  </li>
</ul>
Andres Ilich
la source
D'accord, cela fonctionne, mais maintenant le bouton de suppression ne fonctionne plus, ce que j'aurais pu penser de moi-même. Donc, j'ai probablement besoin de rouvrir le div par programme. Une idée comment faire ça?
Marten Sytema
@MartenSytema tout dépend de la façon dont vous supprimez les produits du menu, mais prenez ceci par exemple: jsfiddle.net/andresilich/E9mpu , remarquez comment j'ai implémenté la .stopPropagation()méthode avec le script de suppression.
Andres Ilich
Merci de votre aide! Le seul problème est que je dois utiliser la méthode jquery en direct pour lier l'événement click, et comme le dit jQuery: puisque la méthode .live () gère les événements une fois qu'ils se sont propagés en haut du document, il n'est pas possible de arrêter la propagation des événements en direct. lien
Marten Sytema
@MartenSytema les deux méthodes font la même chose. De plus, .live()a été obsolète depuis la version 1.7 de jQuery.
Andres Ilich
@MartenSytema a oublié de mentionner, a .live()été remplacé par .on().
Andres Ilich
36

Cette réponse n'est qu'une note secondaire à la réponse acceptée. Merci à l'OP et à Andres pour ces questions et réponses, cela a résolu mon problème. Plus tard, cependant, j'avais besoin de quelque chose qui fonctionnait avec des éléments ajoutés dynamiquement dans ma liste déroulante. Quiconque rencontre celui-ci pourrait également être intéressé par une variante de la solution d'Andres qui fonctionne à la fois avec les éléments initiaux et les éléments ajoutés à la liste déroulante après le chargement de la page:

$(function() {
    $("ul.dropdown-menu").on("click", "[data-keepOpenOnClick]", function(e) {
        e.stopPropagation();
    });
});

Ou, pour les menus déroulants créés dynamiquement:

$(document).delegate("ul.dropdown-menu [data-keepOpenOnClick]", "click", function(e) {
    e.stopPropagation();
});

Ensuite, placez simplement l' data-keepOpenOnClickattribut n'importe où dans l'une des <li>balises ou ses éléments enfants, en fonction de votre situation. PAR EXEMPLE:

<ul class="dropdown-menu">
    <li>
        <-- EG 1: Do not close when clicking on the link -->
        <a href="#" data-keepOpenOnClick>
            ...
        </a>
    </li>
    <li>
        <-- EG 2: Do not close when clicking the checkbox -->
        <input type="checkbox" data-keepOpenOnClick> Pizza
    </li>

    <-- EG 3: Do not close when clicking the entire LI -->
    <li data-keepOpenOnClick>
        ...
    </li>
</ul>
Don Vaughn
la source
20

Sur bootstrap 4, lorsque vous placez un formulaire dans le menu déroulant, il ne s'effondre pas lorsque vous cliquez à l'intérieur.

Donc, cela a fonctionné le mieux pour moi:

<div class="dropdown">
    <!-- toggle button/link -->
    <div class="dropdown-menu">
        <form>
            <!-- content -->
        </form>
    </div>
</div>
Hugo Mota
la source
2
Je ne sais pas comment mais cela fonctionne et devrait être la meilleure réponse.
Dimitri Mostrey
Merci beaucoup d'avoir fourni une réponse qui n'utilise pas jQuery! Fonctionne comme un charme.
Mladen Ristic le
13

En bref, vous pouvez essayer ceci. Ça marche pour moi.

<span class="product-remove">
  <a class="removefromcart" onclick=" event.stopPropagation();" packageid="4" href="#">x</a>
  </span>

la source
3

Le menu s'ouvre lorsque vous donnez une showclasse au menu, vous pouvez donc implémenter la fonction vous-même sans utiliser data-toggle="dropdown".

<div class="dropdown">
  <button class="btn btn-secondary" type="button">
    Dropdown button
  </button>
  <div class="dropdown-menu">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>
<div id="overlay"></div>
#overlay{
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: 1000;
  display: none;
}

#overlay.show{
  display: block;
}

.dropdown-menu{
  z-index: 1001;
}
$('button, #overlay').on('click', function(){
  $('.dropdown-menu, #overlay').toggleClass('show')
})

Essayez ceci dans codepen .

Masamoto Miyata
la source
2

J'avais le même problème avec un sous-menu accordéon / bascule qui était imbriqué dans un menu déroulant dans Bootstrap 3. J'ai emprunté cette syntaxe au code source pour empêcher toutes les bascules de réduction de fermer la liste déroulante:

$(document).on(
    'click.bs.dropdown.data-api', 
    '[data-toggle="collapse"]', 
    function (e) { e.stopPropagation() }
);

Vous pouvez remplacer [data-toggle="collapse"]par ce que vous voulez pour arrêter de fermer le formulaire, de la même manière que @DonamiteIsTnt a ajouté une propriété pour le faire.

Astockwell
la source
1

J'ai écrit quelques lignes de code qui le rendent aussi parfait que nécessaire avec plus de contrôle dessus:

$(".dropdown_select").on('hidden.bs.dropdown', function () {
    if($(this).attr("keep-open") == "true") {
        $(this).addClass("open");
        $(this).removeAttr("keep-open");
    }
});

$(".dropdown_select ul li").bind("click", function (e) {
    // DO WHATEVER YOU WANT
    $(".dropdown_select").attr("keep-open", true);
});
user2991574
la source