Bootstrap putting checkbox in a dropdown

69,189

Solution 1

Here's what we'll build:

Demo

HTML

Essentially, we'll look to combine two different sets of Bootstrap controls & styles: Dropdowns & Checkboxes. Inside of each li, we'll use a label instead of an a element, so that we can wrap the checkbox in a label and make the entire row clickable.

<ul class="dropdown-menu checkbox-menu allow-focus">
  <li >
    <label>
      <input type="checkbox"> Cheese
    </label>
  </li>
</ul>

CSS

We can steal some of the styles normally applied to .dropdown-menu li a, input and apply them to our label option instead. We'll make the label occupy the full width of the container and fix some label / checkbox alignment issues. Additionally, we'll add styles for .active and :hover.

.checkbox-menu li label {
    display: block;
    padding: 3px 10px;
    clear: both;
    font-weight: normal;
    line-height: 1.42857143;
    color: #333;
    white-space: nowrap;
    margin:0;
    transition: background-color .4s ease;
}
.checkbox-menu li input {
    margin: 0px 5px;
    top: 2px;
    position: relative;
}

.checkbox-menu li.active label {
    background-color: #cbcbff;
    font-weight:bold;
}

.checkbox-menu li label:hover,
.checkbox-menu li label:focus {
    background-color: #f5f5f5;
}

.checkbox-menu li.active label:hover,
.checkbox-menu li.active label:focus {
    background-color: #b8b8ff;
}

JavaScript

Some other housekeeping, we'll manually keep an .active class flag on each list item to correspond to whether or not the item is checked so we can style it appropriately.

$(".checkbox-menu").on("change", "input[type='checkbox']", function() {
   $(this).closest("li").toggleClass("active", this.checked);
});

We'll also want to allow multiple selections by allowing the menu to stay open on internal click events by stopping the event from bubbling up

$(document).on('click', '.allow-focus', function (e) {
  e.stopPropagation();
});

Demo in Stack Snippets

$(".checkbox-menu").on("change", "input[type='checkbox']", function() {
   $(this).closest("li").toggleClass("active", this.checked);
});

$(document).on('click', '.allow-focus', function (e) {
  e.stopPropagation();
});
body {
  padding: 15px;
}

.checkbox-menu li label {
    display: block;
    padding: 3px 10px;
    clear: both;
    font-weight: normal;
    line-height: 1.42857143;
    color: #333;
    white-space: nowrap;
    margin:0;
    transition: background-color .4s ease;
}
.checkbox-menu li input {
    margin: 0px 5px;
    top: 2px;
    position: relative;
}

.checkbox-menu li.active label {
    background-color: #cbcbff;
    font-weight:bold;
}

.checkbox-menu li label:hover,
.checkbox-menu li label:focus {
    background-color: #f5f5f5;
}

.checkbox-menu li.active label:hover,
.checkbox-menu li.active label:focus {
    background-color: #b8b8ff;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>



<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" 
          id="dropdownMenu1" data-toggle="dropdown" 
          aria-haspopup="true" aria-expanded="true">
    <i class="glyphicon glyphicon-cog"></i>
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu checkbox-menu allow-focus" aria-labelledby="dropdownMenu1">
  
    <li >
      <label>
        <input type="checkbox"> Cheese
      </label>
    </li>
    
    <li >
      <label>
        <input type="checkbox"> Pepperoni
      </label>
    </li>
    
    <li >
      <label>
        <input type="checkbox"> Peppers
      </label>
    </li>
    
  </ul>
</div>

Solution 2

The way Bootstrap uses checkboxes in their docs is as following:

<div class="checkbox">
    <label>
        <input type="checkbox">Two
    </label>
</div>

So yours would look like:

<ul>
    <li class="dropdown">
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">Dropdown Form<b class="caret"></b></a>
        <ul class="dropdown-menu">
            <li>
                <div class="checkbox">
                    <label>
                        <input type="checkbox">Two
                    </label>
                </div>
            </li>
            <li>
                <div class="checkbox">
                    <label>
                        <input type="checkbox">Two
                    </label>
                </div>
            </li>
        </ul>
    </li>
</ul>

The docs: http://getbootstrap.com/css/#forms

Solution 3

I think a simple solution would be,

<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" 
id="sampleDropdownMenu" data-toggle="dropdown">
Dropdown
</button>
<div class="dropdown-menu">
<button class="dropdown-item" type="button">
 <input type="checkbox">Action
 </button>
<button class="dropdown-item" type="button">
 <input type="checkbox">Action
</button>
<button class="dropdown-item" type="button">
  <input type="checkbox">Action
</button>
</div>
</div>

Solution 4

The problem here is that your checkboxes are being styled (by Bootstrap) with:

.checkbox input[type=checkbox]{
    position: absolute;
    margin-left: -20px;
}

This is probably done to avoid those "bunching" issues you see when you remove the .checkbox class on the <label>, but that negative margin-left is causing problems in this case.

One way to address this with minimal adjustment to your markup and CSS would just be to add some padding on the <label> to account for it:

label.checkbox{
    padding-left:20px;
}

Here's an updated Bootply to show you the code in action. Hope this helps! Let me know if you have any questions.

Share:
69,189
J.Zil
Author by

J.Zil

Updated on June 29, 2020

Comments

  • J.Zil
    J.Zil almost 4 years

    I'm trying to put a checkbox form in a dropdown like this:

    <ul>
      <li class="dropdown">
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">
          Dropdown Form<b class="caret"></b>
        </a>
        <ul class="dropdown-menu">
          <li><label class="checkbox"><input type="checkbox">Two</label></li>
          <li><label class="checkbox"><input type="checkbox">Two</label></li>
        </ul>
      </li>
    </ul>
    

    Here is a Demo in Bootply

    However, as you can see in the demo, for whatever reason the actual checkbox itself appears outside of the dropdown menu. Can anyone tell me what's causing that, and how it should be implemented instead? If I take the label class out it works but it's all bunched up.