bootstrap-table
bootstrap-table copied to clipboard
An option to make the search bar sticky when scroll
Description
In large tables, it would be really helpful to pin the search bar, that way people won't be forced to use CTRL+F, which is really annoying to use on mobile. I've posted in stackoverflow question to try and find a workaround for the time being: https://stackoverflow.com/questions/67858026/change-an-element-to-be-sticky-after-it-render-making-search-input-sticky
But that feature could really be helpful
I found a workaround to manually create another search and set it to work the same. I updated it on the stack-overflow I made at the post, but I keep the suggestion open because I think it can be better impletemented
Awesome thanks! Can you provide an example with your workaround?
Awesome thanks! Can you provide an example with your workaround?
I posted it on stack overflow that I mentioned in the post, but I will post it here as well. A working example can be found on my website - https://www.gamepasscompare.com/games/AllGames
I may have killed a butterfly with a freaking nuke, but since I couldn't find a way to do it "easily" I manually cloned the input and made it fixed. Then manually checked when the original search is out of viewport in order to hide / show it. And copied the CSS from the original to make it look like it sticks.
Here's how I did it, this code is for the bootstrap table search, but you can use it for any input, I tried to leave comments so you can see where you need to edit.
HTML:
Add it anywhere inside the <body>
tag
<div id="stickySeachDiv" class="position-fixed top-0 end-0" style="z-index: 100;">
<!-- sticky search will be added by script into this div -->
</div>
CSS:
copy the properties of your search in terms of padding to create the effect like it's sticky. The hide is just so at startup it will be hidden, as in my case the original input is present on top
#stickySeachDiv {
padding-right: 2%;
display: none;
}
Javascript:
I am using auto-submit search, you can comment it out. don't forget to remove the listener too. Also, I called the CreateStickySearch from pre-bs... you can also modify that, window.onload should work too.
$("#gamesTable").one("pre-body.bs.table", createStickySearch);
function createStickySearch() {
// get hold on the input and clone it
const OriginalSearch = document.querySelector(".fixed-table-toolbar .search input");
const stickySearch = OriginalSearch.cloneNode(true);
stickySearch.addEventListener("keyup", autoSearchHandler);
stickySearch.addEventListener("search", handleStickySearch);
document.querySelector("#stickySeachDiv").appendChild(stickySearch);
// jQuery Listeners, change if you don't use jquery
$(window).on("DOMContentLoaded load resize scroll", stickySearchListener);
}
let time;
function autoSearchHandler() {
// automaticly submit the search after given time
clearTimeout(time);
time = setTimeout(() => submitStickySearch(this.value), 500);
}
function handleStickySearch() {
submitStickySearch(this.value);
}
function submitStickySearch(text) {
$("#table").bootstrapTable("refreshOptions", {
searchText: text
});
}
function revealStickySearch() {
const originalSearch = document.querySelector(".fixed-table-toolbar .search input");
const stickySearchDiv = document.querySelector("#stickySeachDiv");
const stickySearchInput = stickySearchDiv.querySelector('input');
stickySearchDiv.style.display = "block";
stickySearchInput.value = originalSearch.value;
}
function hideStickySearch() {
document.querySelector("#stickySeachDiv").style.display = "none";
}
// Code to see when it should activate, credit to https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport(el) {
// Special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight ||
document.documentElement.clientHeight) /* or $(window).height() */ &&
rect.right <=
(window.innerWidth ||
document.documentElement.clientWidth) /* or $(window).width() */
);
}
let old_visible = true;
function onVisibilityChange(el, onvisible, onNotvisible) {
var visible = isElementInViewport(el);
if(visible !== old_visible) {
old_visible = visible;
visible ? onvisible() : onNotvisible();
}
}
function stickySearchListener() {
const originalSearch = document.querySelector(".fixed-table-toolbar .search input");
onVisibilityChange(originalSearch, hideStickySearch, revealStickySearch);
}
This isn't the prettiest solution, but it works, if anyone find a more elegant solution I will edit my solution.