diff --git a/static/js/utils/asyncTable.js b/static/js/utils/asyncTable.js index 09596f61e..528ad1e1e 100644 --- a/static/js/utils/asyncTable.js +++ b/static/js/utils/asyncTable.js @@ -12,22 +12,21 @@ * (regular table) */ + var INPUT_DEBOUNCE = 600; + var HEADER_HEIGHT = 80; + var ASYNC_TABLE_UTIL_NAME = 'asyncTable'; var ASYNC_TABLE_UTIL_SELECTOR = '[uw-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 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_FILTER_FORM_SELECTOR = '.table-filter-form'; + var ASYNC_TABLE_FILTER_FORM_ID_SELECTOR = '[name="form-identifier"]'; + + var asyncTableUtil = function(element) { var asyncTableHeader; var asyncTableId; @@ -57,9 +56,9 @@ asyncTableId = element.querySelector('table').id; // find scrolltable wrapper - scrollTable = element.querySelector('.scrolltable'); + scrollTable = element.querySelector(ASYNC_TABLE_SCROLLTABLE_SELECTOR); 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(); @@ -86,9 +85,8 @@ ths.forEach(function(th) { th.clickHandler = function(event) { - var horizPos = (scrollTable || {}).scrollLeft; - setLocalStorageParameter('horizPos', horizPos); - clickHandler(event); + setLocalStorageParameter('horizPos', (scrollTable || {}).scrollLeft); + linkClickHandler(event); }; th.element.addEventListener('click', th.clickHandler); }); @@ -112,7 +110,7 @@ }; setLocalStorageParameter('scrollTo', scrollTo); } - clickHandler(event); + linkClickHandler(event); } link.element.addEventListener('click', link.clickHandler); }); @@ -130,7 +128,7 @@ } function setupTableFilter() { - var filterForm = element.querySelector(TABLE_FILTER_FORM_SELECTOR); + var filterForm = element.querySelector(ASYNC_TABLE_FILTER_FORM_SELECTOR); if (filterForm) { gatherTableFilterInputs(); @@ -217,7 +215,7 @@ function serializeTableFilterToURL() { 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) { // cannot serialize the filter form without an identifier return; @@ -252,11 +250,6 @@ return url; } - function reset() { - removeListeners(); - element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS); - } - function processLocalStorage() { var scrollTo = getLocalStorageParameter('scrollTo'); if (scrollTo && scrollTable) { @@ -286,7 +279,7 @@ } } - function clickHandler(event) { + function linkClickHandler(event) { event.preventDefault(); var url = getClickDestination(event.target); if (!url.match(/^http/)) { @@ -317,8 +310,6 @@ throw new Error('HttpClient not found!'); } - console.log('updating from ', { url }); - element.classList.add(ASYNC_TABLE_LOADING_CLASS); var headers = { @@ -334,7 +325,8 @@ }).then(function(data) { setLocalStorageParameter('currentTableUrl', url.href); // reset table - reset(); + removeListeners(); + element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS); // update table with new updateWrapperContents(data); diff --git a/static/js/utils/asyncTableFilter.js b/static/js/utils/asyncTableFilter.js deleted file mode 100644 index 6030ead66..000000000 --- a/static/js/utils/asyncTableFilter.js +++ /dev/null @@ -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() {}, - }; - } -})();