cleanup async table js utility
This commit is contained in:
parent
cef1695fa7
commit
2a311917b3
@ -12,22 +12,21 @@
|
|||||||
* (regular table)
|
* (regular table)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var INPUT_DEBOUNCE = 600;
|
||||||
|
var HEADER_HEIGHT = 80;
|
||||||
|
|
||||||
var ASYNC_TABLE_UTIL_NAME = 'asyncTable';
|
var ASYNC_TABLE_UTIL_NAME = 'asyncTable';
|
||||||
var ASYNC_TABLE_UTIL_SELECTOR = '[uw-async-table]';
|
var ASYNC_TABLE_UTIL_SELECTOR = '[uw-async-table]';
|
||||||
|
|
||||||
var ASYNC_TABLE_LOCAL_STORAGE_KEY = 'ASYNC_TABLE';
|
var ASYNC_TABLE_LOCAL_STORAGE_KEY = 'ASYNC_TABLE';
|
||||||
|
var ASYNC_TABLE_SCROLLTABLE_SELECTOR = '.scrolltable';
|
||||||
var ASYNC_TABLE_INITIALIZED_CLASS = 'async-table--initialized';
|
var ASYNC_TABLE_INITIALIZED_CLASS = 'async-table--initialized';
|
||||||
|
|
||||||
|
|
||||||
var INPUT_DEBOUNCE = 600;
|
|
||||||
|
|
||||||
var HEADER_HEIGHT = 80;
|
|
||||||
var TABLE_FILTER_FORM_SELECTOR = '.table-filter-form';
|
|
||||||
var TABLE_FILTER_FORM_ID_SELECTOR = '[name="form-identifier"]';
|
|
||||||
|
|
||||||
var ASYNC_TABLE_LOADING_CLASS = 'async-table--loading';
|
var ASYNC_TABLE_LOADING_CLASS = 'async-table--loading';
|
||||||
|
|
||||||
|
var ASYNC_TABLE_FILTER_FORM_SELECTOR = '.table-filter-form';
|
||||||
|
var ASYNC_TABLE_FILTER_FORM_ID_SELECTOR = '[name="form-identifier"]';
|
||||||
|
|
||||||
|
|
||||||
var asyncTableUtil = function(element) {
|
var asyncTableUtil = function(element) {
|
||||||
var asyncTableHeader;
|
var asyncTableHeader;
|
||||||
var asyncTableId;
|
var asyncTableId;
|
||||||
@ -57,9 +56,9 @@
|
|||||||
asyncTableId = element.querySelector('table').id;
|
asyncTableId = element.querySelector('table').id;
|
||||||
|
|
||||||
// find scrolltable wrapper
|
// find scrolltable wrapper
|
||||||
scrollTable = element.querySelector('.scrolltable');
|
scrollTable = element.querySelector(ASYNC_TABLE_SCROLLTABLE_SELECTOR);
|
||||||
if (!scrollTable) {
|
if (!scrollTable) {
|
||||||
throw new Error('Async Table cannot be set up without a .scrolltable element!');
|
throw new Error('Async Table cannot be set up without a scrolltable element!');
|
||||||
}
|
}
|
||||||
|
|
||||||
setupSortableHeaders();
|
setupSortableHeaders();
|
||||||
@ -86,9 +85,8 @@
|
|||||||
|
|
||||||
ths.forEach(function(th) {
|
ths.forEach(function(th) {
|
||||||
th.clickHandler = function(event) {
|
th.clickHandler = function(event) {
|
||||||
var horizPos = (scrollTable || {}).scrollLeft;
|
setLocalStorageParameter('horizPos', (scrollTable || {}).scrollLeft);
|
||||||
setLocalStorageParameter('horizPos', horizPos);
|
linkClickHandler(event);
|
||||||
clickHandler(event);
|
|
||||||
};
|
};
|
||||||
th.element.addEventListener('click', th.clickHandler);
|
th.element.addEventListener('click', th.clickHandler);
|
||||||
});
|
});
|
||||||
@ -112,7 +110,7 @@
|
|||||||
};
|
};
|
||||||
setLocalStorageParameter('scrollTo', scrollTo);
|
setLocalStorageParameter('scrollTo', scrollTo);
|
||||||
}
|
}
|
||||||
clickHandler(event);
|
linkClickHandler(event);
|
||||||
}
|
}
|
||||||
link.element.addEventListener('click', link.clickHandler);
|
link.element.addEventListener('click', link.clickHandler);
|
||||||
});
|
});
|
||||||
@ -130,7 +128,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupTableFilter() {
|
function setupTableFilter() {
|
||||||
var filterForm = element.querySelector(TABLE_FILTER_FORM_SELECTOR);
|
var filterForm = element.querySelector(ASYNC_TABLE_FILTER_FORM_SELECTOR);
|
||||||
|
|
||||||
if (filterForm) {
|
if (filterForm) {
|
||||||
gatherTableFilterInputs();
|
gatherTableFilterInputs();
|
||||||
@ -217,7 +215,7 @@
|
|||||||
function serializeTableFilterToURL() {
|
function serializeTableFilterToURL() {
|
||||||
var url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
var url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||||
|
|
||||||
var formIdElement = element.querySelector(TABLE_FILTER_FORM_ID_SELECTOR);
|
var formIdElement = element.querySelector(ASYNC_TABLE_FILTER_FORM_ID_SELECTOR);
|
||||||
if (!formIdElement) {
|
if (!formIdElement) {
|
||||||
// cannot serialize the filter form without an identifier
|
// cannot serialize the filter form without an identifier
|
||||||
return;
|
return;
|
||||||
@ -252,11 +250,6 @@
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
|
||||||
removeListeners();
|
|
||||||
element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
function processLocalStorage() {
|
function processLocalStorage() {
|
||||||
var scrollTo = getLocalStorageParameter('scrollTo');
|
var scrollTo = getLocalStorageParameter('scrollTo');
|
||||||
if (scrollTo && scrollTable) {
|
if (scrollTo && scrollTable) {
|
||||||
@ -286,7 +279,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickHandler(event) {
|
function linkClickHandler(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var url = getClickDestination(event.target);
|
var url = getClickDestination(event.target);
|
||||||
if (!url.match(/^http/)) {
|
if (!url.match(/^http/)) {
|
||||||
@ -317,8 +310,6 @@
|
|||||||
throw new Error('HttpClient not found!');
|
throw new Error('HttpClient not found!');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('updating from ', { url });
|
|
||||||
|
|
||||||
element.classList.add(ASYNC_TABLE_LOADING_CLASS);
|
element.classList.add(ASYNC_TABLE_LOADING_CLASS);
|
||||||
|
|
||||||
var headers = {
|
var headers = {
|
||||||
@ -334,7 +325,8 @@
|
|||||||
}).then(function(data) {
|
}).then(function(data) {
|
||||||
setLocalStorageParameter('currentTableUrl', url.href);
|
setLocalStorageParameter('currentTableUrl', url.href);
|
||||||
// reset table
|
// reset table
|
||||||
reset();
|
removeListeners();
|
||||||
|
element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS);
|
||||||
// update table with new
|
// update table with new
|
||||||
updateWrapperContents(data);
|
updateWrapperContents(data);
|
||||||
|
|
||||||
|
|||||||
@ -1,171 +0,0 @@
|
|||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
window.utils = window.utils || {};
|
|
||||||
|
|
||||||
var ASYNC_TABLE_FILTER_LOADING_CLASS = 'async-table-filter--loading';
|
|
||||||
var JS_INITIALIZED_CLASS = 'js-async-table-filter-initialized';
|
|
||||||
var INPUT_DEBOUNCE = 600;
|
|
||||||
|
|
||||||
// debounce function, taken from Underscore.js
|
|
||||||
function debounce(func, wait, immediate) {
|
|
||||||
var timeout;
|
|
||||||
return function() {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var later = function() {
|
|
||||||
timeout = null;
|
|
||||||
if (!immediate) func.apply(context, args);
|
|
||||||
};
|
|
||||||
var callNow = immediate && !timeout;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(later, wait);
|
|
||||||
if (callNow) func.apply(context, args);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
window.utils.asyncTableFilter = function(formElement, options) {
|
|
||||||
if (!options || !options.updateTableFrom) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formElement.matches('.' + JS_INITIALIZED_CLASS)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var formIdElement = formElement.querySelector('[name="form-identifier"]');
|
|
||||||
if (!formIdElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
options = options || {};
|
|
||||||
var tableIdent = options.dbtIdent;
|
|
||||||
var formId = formIdElement.value;
|
|
||||||
var inputs = {
|
|
||||||
search: [],
|
|
||||||
input: [],
|
|
||||||
change: [],
|
|
||||||
select: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
gatherInputs();
|
|
||||||
addEventListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
function gatherInputs() {
|
|
||||||
Array.from(formElement.querySelectorAll('input[type="search"]')).forEach(function(input) {
|
|
||||||
inputs.search.push(input);
|
|
||||||
});
|
|
||||||
|
|
||||||
Array.from(formElement.querySelectorAll('input[type="text"]')).forEach(function(input) {
|
|
||||||
inputs.input.push(input);
|
|
||||||
});
|
|
||||||
|
|
||||||
Array.from(formElement.querySelectorAll('input:not([type="text"]):not([type="search"])')).forEach(function(input) {
|
|
||||||
inputs.change.push(input);
|
|
||||||
});
|
|
||||||
|
|
||||||
Array.from(formElement.querySelectorAll('select')).forEach(function(input) {
|
|
||||||
inputs.select.push(input);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addEventListeners() {
|
|
||||||
inputs.search.forEach(function(input) {
|
|
||||||
var debouncedInput = debounce(function() {
|
|
||||||
if (input.value.length === 0 || input.value.length > 2) {
|
|
||||||
updateTable();
|
|
||||||
}
|
|
||||||
}, INPUT_DEBOUNCE);
|
|
||||||
input.addEventListener('input', debouncedInput);
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.input.forEach(function(input) {
|
|
||||||
var debouncedInput = debounce(function() {
|
|
||||||
if (input.value.length === 0 || input.value.length > 2) {
|
|
||||||
updateTable();
|
|
||||||
}
|
|
||||||
}, INPUT_DEBOUNCE);
|
|
||||||
input.addEventListener('input', debouncedInput);
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.change.forEach(function(input) {
|
|
||||||
input.addEventListener('change', function() {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.select.forEach(function(input) {
|
|
||||||
input.addEventListener('change', function() {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
formElement.addEventListener('submit', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTable() {
|
|
||||||
var url = serializeFormToURL();
|
|
||||||
var callback = null;
|
|
||||||
|
|
||||||
formElement.classList.add(ASYNC_TABLE_FILTER_LOADING_CLASS);
|
|
||||||
|
|
||||||
var focusedSearch = inputs.search.reduce(function(acc, input) {
|
|
||||||
return acc || (input.matches(':focus') && input);
|
|
||||||
}, null);
|
|
||||||
// focus search input
|
|
||||||
if (focusedSearch) {
|
|
||||||
var selectionStart = focusedSearch.selectionStart;
|
|
||||||
callback = function(wrapper) {
|
|
||||||
var search = wrapper.querySelector('input[type="search"]');
|
|
||||||
if (search) {
|
|
||||||
search.focus();
|
|
||||||
search.selectionStart = selectionStart;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
options.updateTableFrom(url, options, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function serializeFormToURL() {
|
|
||||||
var url = new URL(options.currentUrl || window.location.href);
|
|
||||||
url.searchParams.set('form-identifier', formId);
|
|
||||||
url.searchParams.set('_hasdata', 'true');
|
|
||||||
url.searchParams.set(tableIdent + '-page', '0');
|
|
||||||
|
|
||||||
inputs.search.forEach(function(input) {
|
|
||||||
url.searchParams.set(input.name, input.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.input.forEach(function(input) {
|
|
||||||
url.searchParams.set(input.name, input.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.change.forEach(function(input) {
|
|
||||||
if (input.checked) {
|
|
||||||
url.searchParams.set(input.name, input.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.select.forEach(function(select) {
|
|
||||||
var options = Array.from(select.querySelectorAll('option'));
|
|
||||||
var selected = options.find(function(option) { return option.selected });
|
|
||||||
if (selected) {
|
|
||||||
url.searchParams.set(select.name, selected.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup();
|
|
||||||
|
|
||||||
return {
|
|
||||||
scope: formElement,
|
|
||||||
destroy: function() {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
Reference in New Issue
Block a user