Last active
September 18, 2021 10:31
-
-
Save hmnd/fe4dc8cb82d912037bfab4bff04fbc9b to your computer and use it in GitHub Desktop.
burton: improved view refresh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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