Here's what we'll build:
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.
<!-- language: lang-html -->
<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
.
<!-- language: lang-css -->
.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.
<!-- language: lang-js -->
$(".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
<!-- language: lang-js -->
$(document).on('click', '.allow-focus', function (e) {
e.stopPropagation();
});
Demo in Stack Snippets
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
$(".checkbox-menu").on("change", "input[type='checkbox']", function() {
$(this).closest("li").toggleClass("active", this.checked);
});
$(document).on('click', '.allow-focus', function (e) {
e.stopPropagation();
});
<!-- language: lang-css -->
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;
}
<!-- language: lang-html -->
<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>
<!-- end snippet -->