Manipuladores de eventos para menus suspensos de bootstrap do Twitter?

86

Eu gostaria de usar um botão suspenso do 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 -->

Quando o usuário altera o valor do botão para 'Outra ação', em vez de simplesmente navegar até #, eu realmente gostaria de lidar com a ação de uma forma personalizada.

Mas não consigo ver nenhum manipulador de eventos no plug - in suspenso para fazer isso.

É realmente possível usar os botões suspensos do Bootstrap para controlar as ações do usuário? Estou começando a me perguntar se eles se destinam apenas à navegação - é confuso que o exemplo forneça uma lista de ações.

Richard
fonte
1
Uma função que é disparada ao clicar na tag âncora não funcionaria?
Cameron Chapman de
Em primeiro lugar, não existem botões, são âncoras. Você pode dar uma olhada nos manipuladores de eventos inspecionando o arquivo bootstrap.js. Mas, pelo que eu sei, todas essas ações são processadas com jQuery, portanto, não deve ser um grande problema editar ou substituir essa funcionalidade.
mas-designs de

Respostas:

78

O bootstrap do Twitter tem o objetivo de fornecer uma funcionalidade básica e fornece apenas plug-ins básicos de javascript que fazem algo na tela . Qualquer conteúdo ou funcionalidade adicional, você mesmo terá que fazer.

<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 -->

e então com jQuery

jQuery("#action-1").click(function(e){
//do something
e.preventDefault();
});
Thomas Jones
fonte
1
Tentei isso, entretanto, nenhum evento foi acionado. Posso pegar o evento de clicar em um botão. O que mais pode estar no caminho?
Chave
1
@RonnieKilsbo não tenho certeza. Esta solução funciona conforme declarado e eu a usei inúmeras vezes. Você pode não estar configurando o id da sua âncora corretamente, ou você pode estar vinculando antes que os elementos existam - eu recomendo usar o jQuery's neste caso.
Thomas Jones
1
Você está correto, meu mal. Eu tinha inserido elementos no DOM depois de vincular os clicáveis ​​ao jQuery, o que é uma coisa ruim. :) Trabalhando, confirmou.
Chave
18

Experimente isto:

$('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
fonte
14

No Bootstrap 3, 'dropdown.js' nos fornece os vários eventos que são acionados.

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

etc

Stevanicus
fonte
Isso é verdade, mas você ainda não trabalha dentro da estrutura de bootstrap para anexar manipuladores de eventos. Você faz isso sozinho. O bootstrap sempre tratou de fazer coisas na tela, não fornecer funcionalidade personalizada. Presume-se que o desenvolvedor será capaz de conectar seus próprios eventos suspensos.
Thomas Jones
8

Aqui está um exemplo prático de como você pode implementar funções personalizadas para suas âncoras.

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

Você pode anexar um id à sua âncora:

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

Em seguida, use o ouvinte de evento de clique do jQuery para ouvir a ação de clique e disparar sua função:

$('#alertMe').click(function(e) {
    alert('alerted');
    e.preventDefault();// prevent the default anchor functionality
});
Cameron Chapman
fonte
O exemplo acima parece não existir mais no jsfiddle.
Ethereal
Eu adicionei um novo exemplo com um link válido. Obrigado @ethereal.
Cameron Chapman
4

Eu estive olhando para isso. Ao preencher as âncoras suspensas, dei a elas uma classe e atributos de dados, portanto, quando precisar realizar uma ação, você poderá:

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

e então no jQuery fazendo algo como:

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

Então, se você gerou itens de lista dinamicamente em sua lista suspensa e precisa usar os dados que não são apenas o valor do texto do item, você pode usar os atributos de dados ao criar o item de lista suspensa e então apenas dar a cada item com a classe evento, em vez de se referir ao id de cada item e gerar um evento de clique.

Andrew Berry
fonte
3

Qualquer pessoa aqui procurando a integração do Knockout JS.

Dado o seguinte HTML (botão suspenso Bootstrap padrão):

<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>

Use o seguinte JS:

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

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

Para aqueles que desejam gerar opções suspensas com base na matriz observável de eliminação, o código seria algo como:

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 -->

Observe que o item da matriz observável é passado implicitamente para o manipulador da função de clique para uso no código do modelo de visualização.

pim
fonte
3

Sem ter que alterar seu grupo de botões, você pode fazer o seguinte. Abaixo, suponho que sua lista suspensa buttontenha um 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>

Agora, se você definir o .btn-groupdeste próprio item para ter o idde fldCategory, isso é realmente mais eficiente do jQuery e executado um pouco mais rápido:

<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
fonte
Ha! Obrigado, isso é bom! :) Usei seu segundo exemplo.
drzounds
esta deveria ter sido a resposta!
Jake