web-dev-qa-db-fra.com

Fermer Bootstrap Dropdown après un clic sur un lien

J'ai un menu déroulant d'amorçage ci-dessous. Il contient un lien relié à une liaison knockout.js, qui renvoie false car je ne souhaite pas que la balise # soit envoyée à l'URL du navigateur. Cependant, cela ne ferme pas le menu déroulant lorsque je clique sur le lien. En tout cas autour de ça?

HTML

<div class="btn-group">
    <button class="btn dropdown-toggle" data-toggle="dropdown" data-bind="enable: !noResults()"><i class="icon-download-alt" ></i> Export <span class="icon-caret-down"></span></button>

    <ul class="dropdown-menu">
        @foreach(var exportUrl in Model.ExportUrls)
        {
            <li>
                <a href="#" data-bind="disable: noResults(), download: { url: '@exportUrl.Value', data: data }"><img src="/Content/less/images/img/@(exportUrl.Key.ToString().ToLower()).png" alt="@exportUrl.Key.GetDisplayName()"/> @exportUrl.Key.GetDisplayName()</a>
            </li>
        }
    </ul>
</div>

knockut.js contraignant

ko.bindingHandlers.download = {
    init: function (element, valueAccessor) {

        var value = ko.utils.unwrapObservable(valueAccessor()),
            id = 'download-iframe-container',
            iframe;

        $(element).unbind('click').bind('click', function () {

            iframe = document.getElementById(id);

            if (!iframe) {
                iframe = document.createElement("iframe");
                iframe.id = id;
                iframe.style.display = "none";
            }

            if (value.data) {
                iframe.src = value.url + (value.url.indexOf('?') > 0 ? '&' : '?') + $.param(ko.mapping.toJS(value.data));
            } else {
                iframe.src = value.url;
            }

            document.body.appendChild(iframe);

            return false;
        });
    }
};
44
Mike Flynn

Attribuez une classe à vos liens (téléchargement, par exemple):

<a href="#" class="download" data-bind="disable: noResults()....

Et votre liste déroulante un identifiant (par exemple, dlDropDown):

<button class="btn dropdown-toggle" id="dlDropDown" data-toggle="dropdown" data-bind="enable: !noResults()">

Et ajoutez ensuite le gestionnaire d'événements suivant:

$("a.download").click(function() {
   $("#dlDropDown").dropdown("toggle");
});
49
mccannf

Cela fonctionnera réellement avec votre balisage de démarrage existant sans avoir à ajouter de nouvelles classes ou identifiants. J'espère que cela sera utile à quelqu'un qui voudrait simplement laisser tomber une solution sans rien changer.

$(".dropdown-menu a").click(function() {
    $(this).closest(".dropdown-menu").prev().dropdown("toggle");
});
34
brianespinosa

Ceci peut être réalisé avec les bootstraps de la classe CSS dropdown-toggle

Ajoutez simplement cette classe à vos éléments de lien, comme ceci: <a class='dropdown-toggle'></a> et le menu déroulant sera basculé.

19
nullwriter

Je pense que cela fermera tous les menus déroulants et les menus de navigation étendus sur la page:

$('.in,.open').removeClass('in open');
12
Tom

Utiliser event.preventDefault() au lieu de return false fait l'affaire.

Changez votre code pour:

$(element).unbind('click').bind('click', function(e) {
  e.preventDefault();

  // ...

  return true; // or just remove the return clause
});
5
Fábio Batista

Malheureusement, je n'ai pas réussi à utiliser .dropdown('toggle') comme suggéré ci-dessus ...

Cependant, ce qui a bien fonctionné a été d'appliquer les attributs de données du bouton déroulant de bootstrap à ses propres liens déroulants:

<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle navbar-btn">

...

<ul class="nav navbar-nav">
  <li><a href="#about" class="scroll-to" data-toggle="collapse" data-target=".navbar-collapse">About</a></li>

Tout ce que je fis, c’est d’ajouter les data-toggle="collapse" et data-target=".navbar-collapse" à chaque lien de navigation déroulant. 

Aucun css ou js supplémentaire et cela a fonctionné comme un charme :)

5
Jesse Novotny

Changez simplement le href="#" en href="javscript:void(0);" puis return true dans votre événement click (au lieu de false

4
Rich

Une solution plus propre pour conserver la fonctionnalité de liste déroulante et obtenir ce que vous recherchez.

$("body").on('click', function (e) {
     if (!$(e.target).hasClass("open") && $(e.target).parents(".btn-group.open").length == 0)
         $(this).find(".btn-group.open a").trigger("click");
});
1
Raúl Cantú

Si vous avez un paramètre d'événement, faites simplement:

$(element).unbind('click').bind('click', function (event)
{
    event.preventDefault();
    return true;
});
1
Dave

vous pouvez également ajouter un masque transparent pour bloquer tout autre clic indésirable lorsque la liste déroulante est ouverte:

   OnDomReadyHeaderItem.forScript("$('.dropdown').on('shown.bs.dropdown', function (e) { $(this).append('<span id=\"transparent-mask\"></span>')})"));

   OnDomReadyHeaderItem.forScript("$('.dropdown').on('hidden.bs.dropdown', function (e) { $('#transparent-mask').remove()})"));

avec le masque:

.dropdown.open #transparent-mask{
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: block;
    margin: auto;
    height: initial;
    z-index: 1000 !important;
}
0
daniel gi

la meilleure réponse sera de cliquer afin que l'utilisateur agisse de la même façon que l'utilisateur clique avec la souris pour masquer le menu déroulant. Pour ce faire, ajoutez ce code d'instantané à votre page:

<script>
    $(document).ready(function () {
        $("li.dropdown ul.dropdown-menu li").click(function (event) {
            event.toElement.parentElement.click();
        })
    })
</script>
0
Akram Kamal Qassas