This is my debut answer on SO, so any constructive feedback is highly appreciated.
I recently achieved this feat by following these steps:
Set the "frozen at top" items' position to "fixed" in CSS and make necessary adjustments to ensure that the remaining items are not visible behind them when the dropdown expands.
Invoke a function (refer to resetDropdownHeight()
in the fiddle below) in the multiselect's onDropdownShown
event to adjust the expanded dropdown's height based on the frozen items' height.
To maintain correct dropdown height during filtering, modify the buildFilter:
function in bootstrap-multiselect.js to incorporate the resetDropdownHeight()
function. If collapsible option groups are used, do the same within the click event for
$('li.multiselect-group > a', this.$ul)
.
Although demonstrating item #3 (above) in the example fiddle was challenging, here are the instances where you should call resetDropdownHeight()
in your modified version of bootstrap-multiselect.js:
buildFilter:
1. Call it as the final line of the clearBtn.on
event
2. Call it as the last line of the extensive function for this.searchTimeout
"click" event for
$('li.multiselect-group > a', this.$ul)
:
1. Call it as the ultimate line of the event
Check out an example here (includes #1 and #2 only): https://jsfiddle.net/mjh42/v3bc9udk/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://davidstutz.github.io/bootstrap-multiselect/dist/css/bootstrap-multiselect.css"/>
<script type="text/javascript" src="https://davidstutz.github.io/bootstrap-multiselect/dist/js/bootstrap-multiselect.js"></script>
<style type="text/css">
#freezeDemo + div.btn-group li.multiselect-filter {
position: fixed;
left: 1px;
top: 35px;
width: 162px;
z-index: 10;
background-color: white;
}
#freezeDemo + div.btn-group li.multiselect-all {
position: fixed;
left: 1px;
top: 75px;
width: 162px;
z-index: 10;
background-color: white;
border-bottom: 1px solid;
}
#freezeDemo + div.btn-group ul.multiselect-container.dropdown-menu > li:not(.multiselect-filter):not(.multiselect-all) {
position: relative;
top: 65px;
}
#freezeDemo + div.btn-group ul.multiselect-container.dropdown-menu {
top: 34px;
width: 180px;
}
</style>
</head>
<body>
<select id="freezeDemo" multiple="multiple">
<optgroup label="Group A">
<option value="A1">Item A1</option>
<option value="A2">Item A2</option>
<option value="A3">Item A3</option>
<option value="A4">Item A4</option>
<option value="A5">Item A5</option>
</optgroup>
<optgroup label="Group B">
<option value="B1">Item B1</option>
<option value="B2">Item B2</option>
<option value="B3">Item B3</option>
<option value="B4">Item B4</option>
<option value="B5">Item B5</option>
</optgroup>
</select>
<script type="text/javascript">
var $_dropdownMenu = null;
initializeBootstrapMultiselect();
function initializeBootstrapMultiselect() {
$('#freezeDemo').multiselect({
buttonWidth: '180px',
enableCollapsibleOptGroups: true,
includeSelectAllOption: true,
enableFiltering: true,
enableCaseInsensitiveFiltering: true,
maxHeight: 200,
onDropdownShown: function(event) {
resetDropdownHeight();
}
});
$_dropdownMenu = $('#freezeDemo + div.btn-group > button.multiselect.dropdown-toggle.btn.btn-default ~ ul.multiselect-container.dropdown-menu');
}
function resetDropdownHeight() {
if ($_dropdownMenu !== null) {
$_dropdownMenu.css('height', 'auto');
var filterHeight = $('li.multiselect-filter', $_dropdownMenu).height();
var selectAllHeight = $('li.multiselect-all', $_dropdownMenu).height();
if (isNaN(filterHeight)) { filterHeight = 0 }
if (isNaN(selectAllHeight)) { selectAllHeight = 0 }
var heightAdjustment = filterHeight + selectAllHeight;
var currentDropdownHeight = $_filterDropdownMenu.height();
var newHeight = (currentDropdownHeight + heightAdjustment).toString() + 'px';
$_dropdownMenu.css('height', newHeight);
}
}
</script>
</body>
</html>