Skip to content

Instantly share code, notes, and snippets.

@hmnd
Last active September 18, 2021 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hmnd/fe4dc8cb82d912037bfab4bff04fbc9b to your computer and use it in GitHub Desktop.
Save hmnd/fe4dc8cb82d912037bfab4bff04fbc9b to your computer and use it in GitHub Desktop.
burton: improved view refresh
/**
* Construct Knack events for multiple keys
*
* @param {string[]} keys - Event keys
* @param {string} eventType - Knack event type
* @param {JQuery.EventHandler} handler - Event handler
* @param {boolean} [once] - Handle event only once
*/
function knackEventHandlers(keys, eventType, handler, once) {
const handleEvent = once ? $(document).one : $(document).on;
handleEvent.apply($(document), [keys.map((key) => `knack-${eventType}.${key}`).join(' '), handler]);
}
/**
* Constructs view refresh handler with given delay
*
* @param {string[]} viewKeys
* @param {number} delayMs
*/
const constructDelayedViewRefreshHandler = (viewKeys, delayMs) =>
knackEventHandlers(viewKeys, 'view-init', (_e, view) => {
const {
el: viewEl,
model: {
view: { key: viewKey },
},
} = view;
knackEventHandlers(
[viewKey],
'view-render',
() => {
const refreshInterval = setInterval(() => {
if (!document.contains(viewEl)) {
return clearInterval(refreshInterval);
}
const liveSearchQuery = decodeURIComponent(Knack.getHashVar(`${viewKey}_search`) || '');
const elements = {
get searchInput() {
return viewEl.querySelector('form.table-keyword-search input[name="keyword"]');
},
get searchBtn() {
return viewEl.querySelector('.kn-button.search');
},
get tableWrapper() {
return viewEl.querySelector('.kn-table-wrapper');
},
};
const searchIsActive =
elements.searchInput &&
(document.activeElement === elements.searchInput || elements.searchInput.value !== liveSearchQuery);
if (searchIsActive) {
return;
}
if (elements.searchInput) {
elements.searchBtn.classList.add('is-loading');
elements.searchInput.disabled = true;
}
const prevScrollPos = elements.tableWrapper.scrollTop;
const restore = () => {
if (elements.searchInput) {
elements.searchInput.disabled = false;
elements.searchBtn.classList.remove('is-loading');
}
if (prevScrollPos > 0) {
window.scrollBy(0, 1);
setTimeout(() => {
window.scrollBy(0, -1);
setTimeout(() => {
elements.tableWrapper.scrollTop = prevScrollPos;
}, 50);
}, 500);
}
};
view.model.fetch({
success() {
restore();
},
error() {
restore();
},
});
}, delayMs);
},
true
);
});
constructDelayedViewRefreshHandler(['view_XXX'], 5000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment