JSFiddle - React, Tailwind, and code Playground
by Martin_ATS
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css">
<div id="header">Header</div>
<div id="menucontainer" class="container-fluid align-items-center p-2">
<div class="d-flex">
<div class="dropdown position-static">
<div class="btn btn-primary dropdown-toggle me-2" data-bs-toggle="dropdown" data-bs-display="dynamic" data-bs-container="body" data-bs-auto-close="outside" id="country_trigger">
Select countries
</div>
<div id="country" class="dropdown-menu shadow-4-strong p-2" aria-labelledby="country_trigger">
<div class="d-flex flex-column flex-wrap justify-content-start align-items-stretch">
<div class="itemwrapper">
<div class="dropdown-header">
North America
</div>
<div class="colitem">
<div class="form-check" data-id="US" title="US">
<input class="form-check-input" type="checkbox" value="" id="countryList-1">
<label class="form-check-label" for="countryList-1">
United States
</label>
</div>
</div>
<div class="colitem">
<div class="form-check" data-id="CA" title="CA">
<input class="form-check-input" type="checkbox" value="" id="countryList-2">
<label class="form-check-label" for="countryList-2">
Canada
</label>
</div>
</div>
<div class="dropdown-header">
Central America
</div>
<div class="colitem disabled">
<div class="form-check disabled menuitemdisabled" data-id="CR" data-pk="-1">
<input class="form-check-input" type="checkbox" value="" id="countryList-3" disabled="">
<label class="form-check-label" for="countryList-3">
Costa...
CSS
body {
padding: 30px;
}
.dropdown-header {
color: cadetblue;
font-weight: 600;
break-after: avoid;
}
.ddcols .itemgroup {
margin-bottom: 16px;
}
#header {
width: 100%;
font-size: 1.5rem;
text-align: center;
background-color: lightgray;
line-height: 3rem;
padding: 15px;
}
#menucontainer {
width: 100%;
background-color: cornflowerblue;
}
#menucontainer .dropdown-menu {
width: calc(100vw - 60px);
margin-right: 30px;
}
.itemwrapper {
column-width: 150px;
column-gap: 1.5em;
column-fill: balance;
max-height: 50vh;
overflow-x: auto;
padding: 0.5em;
margin-bottom: 0.5em;
background-color: paleturquoise;
}
.itemwrapper .dropdown-header {
padding-left: 0;
}
.colitem {
break-inside: avoid;
overflow: hidden;
line-height: 1.2em;
margin-bottom: 5px;
}
.colitem .form-check .form-check-input {
margin-top: 1px;
}
JavaScript
$(() => {
var autoHideCt = 0;
function hideDropdown($ddelem, method) {
$ddelem.removeData('autohide');
if (method === 1) {
var dd = bootstrap.Dropdown.getInstance($ddelem.get(0));
console.log('auto-hide dropdown method 1...');
dd.hide();
} else if (method === 2) {
console.log('auto-hide dropdown method 2...');
$ddelem.dropdown('hide');
} else {
throw `Unknown auto-hide method ${method}`;
}
}
$('.dropdown')
.on('show.bs.dropdown', (evt) => {
var dd = bootstrap.Dropdown.getInstance(evt.relatedTarget);
console.log(`show.bs.dropdown ${evt.relatedTarget.id}`);
})
.on('shown.bs.dropdown', (evt) => {
var dd = bootstrap.Dropdown.getInstance(evt.relatedTarget);
console.log(`shown.bs.dropdown ${evt.relatedTarget.id}`);
var $ddelem = $(evt.relatedTarget);
// auto-hide after 5 seconds
$ddelem.data('autohide', window.setTimeout(() => { hideDropdown($ddelem, autoHideCt++ % 2 + 1); }, 5000));
})
.on('hide.bs.dropdown', (evt) => {
var $ddelem = $(evt.relatedTarget);
console.log(`hide.bs.dropdown ${$ddelem.attr('id')}`);
var tmr = $ddelem.data('autohide');
if (tmr) {
window.clearTimeout(tmr);
$ddelem.removeData('autohide');
}
})
.on('hidden.bs.dropdown', (evt) => {
console.log(`hidden.bs.dropdown ${evt.relatedTarget.id}`);
})
});