[javascript] Event handlers for Twitter Bootstrap dropdowns?

I'd like to use a Twitter Bootstrap dropdown button:

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

When the user changes the value of the button to 'Another action', instead of simply navigating to #, I'd actually like to handle the action in a custom way.

But I can't see any event handlers in the dropdown plugin for doing this.

Is it actually possible to use Bootstrap dropdown buttons to handle user actions? I'm starting to wonder if they're only intended for navigation - it's confusing that the example gives a list of actions.

This question is related to javascript twitter-bootstrap

The answer is


Try this:

$('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;
});

In Bootstrap 3 'dropdown.js' provides us with the various events that are triggered.

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

etc


Without having to change your button group at all, you can do the following. Below, I assume your dropdown button has an id of 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>

Now, if you set the .btn-group of this item itself to have the id of fldCategory, that's actually more efficient jQuery and runs a little faster:

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

Here you go, options have values, label and css classes that gets reflected on parent element upon selection.

_x000D_
_x000D_
$(document).on('click','.update_app_status', function (e) {
            let $div = $(this).parent().parent(); 
            let $btn = $div.find('.vBtnMain');
            let $btn2 = $div.find('.vBtnArrow');
            let cssClass = $(this).data('status_class');
            let status_value = $(this).data('status_value');
            let status_label = $(this).data('status_label');
            $btn.html(status_label);
            $btn.removeClass();
            $btn2.removeClass();
            $btn.addClass('btn btn-sm vBtnMain '+cssClass);
            $btn2.addClass('btn btn-sm vBtnArrow dropdown-toggle dropdown-toggle-split '+cssClass);
            $div.removeClass('show');
            $div.find('.dropdown-menu').removeClass('show');
            e.preventDefault();
            return false;
    });
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>


  

   <div class="btn-group">
   <button type="button" class="btn btn-sm vBtnMain btn-warning">Awaiting Review</button>
   <button type="button" class="btn btn-sm vBtnArrow btn-warning dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
       <span class="sr-only">Toggle Dropdown</span>
   </button>
   <div class="dropdown-menu dropdown-menu-right">
     <a class="dropdown-item update_app_status" data-status_class="btn-warning" data-status_value="1" data-status_label="Awaiting Review" href="#">Awaiting Review</a>
     <a class="dropdown-item update_app_status" data-status_class="btn-info" data-status_value="2" data-status_label="Reviewed" href="#">Reviewed</a>
     <a class="dropdown-item update_app_status" data-status_class="btn-dark" data-status_value="3" data-status_label="Contacting" href="#">Contacting</a>
     <a class="dropdown-item update_app_status" data-status_class="btn-success" data-status_value="4" data-status_label="Hired" href="#">Hired</a>
     <a class="dropdown-item update_app_status" data-status_class="btn-danger" data-status_value="5" data-status_label="Rejected" href="#">Rejected</a>
   </div>
   </div>
_x000D_
_x000D_
_x000D_


I have been looking at this. On populating the drop down anchors, I have given them a class and data attributes, so when needing to do an action you can do:

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

and then in the jQuery doing something like:

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

So if you have dynamically generated list items in your dropdown and need to use the data that isn't just the text value of the item, you can use the data attributes when creating the dropdown listitem and then just give each item with the class the event, rather than referring to the id's of each item and generating a click event.


Here is a working example of how you could implement custom functions for your anchors.

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

You can attach an id to your anchor:

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

And then use jQuery's click event listener to listen for the click action and fire you function:

$('#alertMe').click(function(e) {
    alert('alerted');
    e.preventDefault();// prevent the default anchor functionality
});

Anyone here looking for Knockout JS integration.

Given the following HTML (Standard Bootstrap dropdown button):

<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 the following JS:

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

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

For those looking to generate dropdown options based on knockout observable array, the code would look something like:

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

Note, that the observable array item is implicitly passed into the click function handler for use in the view model code.