Keep Tom Select Dropdown on screen
https://github.com/orchidjs/tom-select/discussions/393
by Mdot
HTML
<script src="https://cdn.jsdelivr.net/gh/orchidjs/[email protected]/dist/js/tom-select.complete.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orchidjs/[email protected]/dist/css/tom-select.bootstrap5.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<div class="p-4 container"> <select id="select-tags" multiple placeholder="Best movies and TV shows">
<optgroup label="TV Shows">
<option value="Blue Bloods" data-date="2010-2021">Blue Bloods (2010-2021)</option>
<option value="Magnum P.I." data-date="1980-1988" selected>Magnum P.I. (1980-1988)</option>
</optgroup>
<optgroup label="Movies">
<option value="An Innocent Man" data-date="1989">An Innocent Man (1989)</option>
<option value="In & Out" data-date="1997">In & Out (1997)</option>
<option value="Lassiter" data-date="1984">Lassiter (1984)</option>
<option value="Mr. Baseball" data-date="1992">Mr. Baseball (1992)</option>
<option value="Quigley Down Under" data-date="1990">Quigley Down Under (1990)</option>
<option value="Three Men and a Baby" data-date="1987">Three Men and a Baby (1987)</option>
</optgroup>
</select>
</div>
CSS
html {
height: 200vh;
}
.container {
margin-top: 80vh;
}
.ts-control.dropdown-top .ts-dropdown,
.ts-wrapper.dropdown-top .ts-dropdown {
bottom: 100%;
top: auto;
}
JavaScript
new TomSelect("#select-tags", {
onInitialize: function() {
this.dropdownWatch = null;
this.dropdownWatchCb = () => {
if (this.isOpen) {
const controlRect = this.control.getBoundingClientRect();
const dropdownRect = this.dropdown.getBoundingClientRect();
const spaceAbove = controlRect.top;
const spaceBelow = window.innerHeight - controlRect.bottom;
if (
spaceBelow < dropdownRect.height && spaceAbove > spaceBelow
) {
this.wrapper.classList.add('dropdown-top');
} else {
this.wrapper.classList.remove('dropdown-top');
}
}
}
},
onDropdownOpen: function() {
this.dropdownWatchCb();
this.dropdownWatch = setInterval(this.dropdownWatchCb, 250);
},
onDropdownClose: function() {
clearInterval(this.dropdownWatch)
},
});