Gestionnaires d'événements pour les listes déroulantes Twitter Bootstrap?

86

Je souhaite utiliser un bouton déroulant Twitter Bootstrap :

    <div class="btn-group">
      <button class="btn dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
      <ul class="dropdown-menu">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
      </ul>
    </div><!-- /btn-group -->

Lorsque l'utilisateur change la valeur du bouton en "Une autre action", au lieu de simplement naviguer vers #, j'aimerais en fait gérer l'action de manière personnalisée.

Mais je ne vois aucun gestionnaire d'événements dans le plugin déroulant pour faire cela.

Est-il réellement possible d'utiliser les boutons déroulants Bootstrap pour gérer les actions de l'utilisateur? Je commence à me demander s'ils sont uniquement destinés à la navigation - il est déroutant que l'exemple donne une liste d'actions.

Richard
la source
1
Une fonction qui est déclenchée en cliquant sur la balise d'ancrage ne fonctionnerait-elle pas?
Cameron Chapman
Tout d'abord, ce ne sont pas des boutons, ce sont des ancres. Vous pouvez jeter un œil aux gestionnaires d'événements en inspectant le fichier bootstrap.js. Mais pour autant que je sache, toutes ces actions sont traitées avec jQuery, il ne devrait donc pas être un gros problème de modifier ou de remplacer cette fonctionnalité.
mas-designs

Réponses:

78

Le bootstrap de Twitter est destiné à donner une fonctionnalité de base et ne fournit que des plugins javascript de base qui font quelque chose à l'écran . Tout contenu ou fonctionnalité supplémentaire, vous devrez le faire vous-même.

<div class="btn-group">
  <button class="btn dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
  <ul class="dropdown-menu">
    <li><a href="#" id="action-1">Action</a></li>
    <li><a href="#" id="action-2">Another action</a></li>
    <li><a href="#" id="action-3">Something else here</a></li>
  </ul>
</div><!-- /btn-group -->

puis avec jQuery

jQuery("#action-1").click(function(e){
//do something
e.preventDefault();
});
Thomas Jones
la source
1
J'ai essayé cela, cependant, sans qu'aucun événement ne se déclenche. Je peux cependant saisir l'événement en cliquant sur un bouton. Qu'y a-t-il d'autre sur le chemin?
Clé du
1
@RonnieKilsbo pas sûr. Cette solution fonctionne comme indiqué et je l'ai utilisée d'innombrables fois. Vous ne définissez peut-être pas correctement l'identifiant de votre ancre, ou vous pouvez être lié avant que les éléments n'existent - je recommande vivement d'utiliser jQuery dans ce cas.
Thomas Jones
1
Vous avez raison, mon mauvais. J'avais inséré des éléments dans le DOM après avoir lié les cliquables avec jQuery, ce qui est une mauvaise chose. :) En marche, confirmé.
Clé du
18

Essaye ça:

$('div.btn-group ul.dropdown-menu li a').click(function (e) {
    var $div = $(this).parent().parent().parent(); 
    var $btn = $div.find('button');
    $btn.html($(this).text() + ' <span class="caret"></span>');
    $div.removeClass('open');
    e.preventDefault();
    return false;
});
Fernando
la source
14

Dans Bootstrap 3, «dropdown.js» nous fournit les différents événements déclenchés.

click.bs.dropdown
show.bs.dropdown
shown.bs.dropdown

etc

Stevanicus
la source
C'est vrai, mais vous ne travaillez toujours pas dans le cadre de bootstrap pour attacher des gestionnaires d'événements. Vous faites cela par vous-même. Bootstrap a toujours consisté à faire des choses à l'écran, sans fournir de fonctionnalités personnalisées. Il est supposé que les développeurs seront en mesure de connecter leurs propres événements de liste déroulante.
Thomas Jones
8

Voici un exemple fonctionnel de la façon dont vous pouvez implémenter des fonctions personnalisées pour vos ancres.

http://jsfiddle.net/CH2NZ/43/

Vous pouvez joindre un identifiant à votre ancre:

<li><a id="alertMe" href="#">Action</a></li>

Et puis utilisez l'écouteur d'événement click de jQuery pour écouter l'action de clic et déclencher votre fonction:

$('#alertMe').click(function(e) {
    alert('alerted');
    e.preventDefault();// prevent the default anchor functionality
});
Cameron Chapman
la source
L'exemple ci-dessus ne semble plus exister sur jsfiddle.
Ethereal
J'ai ajouté un nouvel exemple avec un lien valide. Merci @ethereal.
Cameron Chapman
4

J'ai regardé ceci. En remplissant les ancres déroulantes, je leur ai donné une classe et des attributs de données, donc lorsque vous avez besoin de faire une action, vous pouvez faire:

<li><a class="dropDownListItem" data-name="Fred Smith" href="#">Fred</a></li>

puis dans le jQuery en faisant quelque chose comme:

$('.dropDownListItem').click(function(e) {
    var name = e.currentTarget;
    console.log(name.getAttribute("data-name"));
});

Donc, si vous avez des éléments de liste générés dynamiquement dans votre liste déroulante et que vous devez utiliser des données qui ne sont pas seulement la valeur textuelle de l'élément, vous pouvez utiliser les attributs de données lors de la création de l'élément de liste déroulante, puis attribuer simplement à chaque élément avec la classe le événement, plutôt que de faire référence aux identifiants de chaque élément et de générer un événement de clic.

Andrew Berry
la source
3

Tous ceux qui recherchent l'intégration de Knockout JS.

Compte tenu du code HTML suivant (bouton déroulant Standard Bootstrap):

<div class="dropdown">
    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
        Select an item               
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
        <li>
            <a href="javascript:;" data-bind="click: clickTest">Click 1</a>
        </li>
        <li>
            <a href="javascript:;" data-bind="click: clickTest">Click 2</a>
        </li>
        <li>
            <a href="javascript:;" data-bind="click: clickTest">Click 3</a>
        </li>
    </ul>
</div>

Utilisez le JS suivant:

var viewModel = function(){
    var self = this;

    self.clickTest = function(){
        alert("I've been clicked!");
    }  
};

Pour ceux qui cherchent à générer des options de liste déroulante basées sur un tableau observable knockout, le code ressemblerait à quelque chose comme:

var viewModel = function(){
    var self = this;

    self.dropdownOptions = ko.observableArray([
        { id: 1, label: "Click 1" },
        { id: 2, label: "Click 2" },
        { id: 3, label: "Click 3" }
    ])

    self.clickTest = function(item){
        alert("Item with id:" + item.id + " was clicked!");
    }  
};

<!-- REST OF DD CODE -->
<ul class="dropdown-menu" role="menu">
    <!-- ko foreach: { data: dropdownOptions, as: 'option' } -->
    <li>
        <a href="javascript:;" data-bind="click: $parent.clickTest, text: option.clickTest"></a>
    </li>
    <!-- /ko -->
</ul>
<!-- REST OF DD CODE -->

Notez que l'élément de tableau observable est implicitement passé dans le gestionnaire de fonction de clic pour être utilisé dans le code du modèle de vue.

pim
la source
3

Sans avoir à modifier du tout votre groupe de boutons, vous pouvez effectuer les opérations suivantes. Ci - dessous, je suppose que votre menu déroulant buttona un idde fldCategory.

<script type="text/javascript">

$(document).ready(function(){

  $('#fldCategory').parent().find('UL LI A').click(function (e) {
    var sVal = e.currentTarget.text;
    $('#fldCategory').html(sVal + ' <span class="caret"></span>');
    console.log(sVal);
  });

});

</script>

Maintenant, si vous définissez le .btn-groupde cet élément lui-même pour avoir le idof fldCategory, c'est en fait jQuery plus efficace et s'exécute un peu plus vite:

<script type="text/javascript">

$(document).ready(function(){

  $('#fldCategory UL LI A').click(function (e) {
    var sVal = e.currentTarget.text;
    $('#fldCategory BUTTON').html(sVal + ' <span class="caret"></span>');
    console.log(sVal);
  });

});

</script>
Volomike
la source
Ha! Merci c'est super! :) J'ai utilisé votre 2ème exemple.
drzounds le
cela aurait dû être la réponse!
Jake