Event handlers for Twitter Bootstrap dropdowns?

JavascriptTwitter Bootstrap

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

Twitter bootstrap is meant to give a baseline functionality, and provides only basic javascript plugins that do something on screen. Any additional content or functionality, you'll have to do yourself.

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

and then with jQuery

jQuery("#action-1").click(function(e){
//do something
e.preventDefault();
});

Solution 2 - Javascript

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;
});

Solution 3 - Javascript

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

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

etc

Solution 4 - Javascript

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
});

Solution 5 - Javascript

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.

Solution 6 - Javascript

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.

Solution 7 - Javascript

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>

Solution 8 - Javascript

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

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - JavascriptThomas JonesView Answer on Stackoverflow
Solution 2 - JavascriptFernandoView Answer on Stackoverflow
Solution 3 - JavascriptStevanicusView Answer on Stackoverflow
Solution 4 - JavascriptCameron ChapmanView Answer on Stackoverflow
Solution 5 - JavascriptAndrew BerryView Answer on Stackoverflow
Solution 6 - JavascriptpimView Answer on Stackoverflow
Solution 7 - JavascriptVolomikeView Answer on Stackoverflow
Solution 8 - JavascriptHimanshu SainiView Answer on Stackoverflow