|  |  |  | @ -43,14 +43,18 @@ document.addEventListener('DOMContentLoaded', function () { | 
		
	
		
			
				|  |  |  |  |     }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     function dynamicTables() { | 
		
	
		
			
				|  |  |  |  |         const pageSize = 25 | 
		
	
		
			
				|  |  |  |  |         const pageSize = 40 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         const range = (x, y) => | 
		
	
		
			
				|  |  |  |  |               x > y ? [] : [x, ...range(x + 1, y)]; | 
		
	
		
			
				|  |  |  |  |             x > y ? [] : [x, ...range(x + 1, y)]; | 
		
	
		
			
				|  |  |  |  |         const visibleRows = page => | 
		
	
		
			
				|  |  |  |  |               range(page * pageSize, (page + 1) * pageSize - 1) | 
		
	
		
			
				|  |  |  |  |             range(page * pageSize, (page + 1) * pageSize - 1) | 
		
	
		
			
				|  |  |  |  |         const tblRows = tbl => | 
		
	
		
			
				|  |  |  |  |               [...tbl.tBodies[0].rows] | 
		
	
		
			
				|  |  |  |  |             [...tbl.tBodies[0].rows] | 
		
	
		
			
				|  |  |  |  |         const partial11 = (fn, arg1) => | 
		
	
		
			
				|  |  |  |  |             function (arg2) { | 
		
	
		
			
				|  |  |  |  |                 fn(arg1, arg2) | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function toggleVisibilities(tbl, ixsToShow) { | 
		
	
		
			
				|  |  |  |  |             tblRows(tbl).forEach(function (row, ix) { | 
		
	
	
		
			
				
					|  |  |  | @ -58,61 +62,48 @@ document.addEventListener('DOMContentLoaded', function () { | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function setCurrPage(tbl, currPageIx) { | 
		
	
		
			
				|  |  |  |  |             const elems = document.querySelectorAll('.tbl-toolbar .row-info') | 
		
	
		
			
				|  |  |  |  |             const rows = tbl.tBodies[0].rows.length | 
		
	
		
			
				|  |  |  |  |         function setCurrPage(ctx, currPageIx) { | 
		
	
		
			
				|  |  |  |  |             const rows = tblRows(ctx.tbl).length | 
		
	
		
			
				|  |  |  |  |             const pages = Math.ceil(rows / pageSize) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             elems.forEach(function(elem) { | 
		
	
		
			
				|  |  |  |  |                 elem.children[0].innerText = (currPageIx + 1) + ' / ' + pages | 
		
	
		
			
				|  |  |  |  |                 elem.children[1].innerText = rows | 
		
	
		
			
				|  |  |  |  |             ctx.rowsLbls.forEach(function (elem) { | 
		
	
		
			
				|  |  |  |  |                 elem.innerText = rows | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             ctx.pageLbls.forEach(function (elem) { | 
		
	
		
			
				|  |  |  |  |                 elem.innerText = (currPageIx + 1) + ' / ' + pages | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             tbl.setAttribute('data-page', currPageIx) | 
		
	
		
			
				|  |  |  |  |             ctx.tbl.setAttribute('data-page', currPageIx) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function changePage(tbl, ix) { | 
		
	
		
			
				|  |  |  |  |             toggleVisibilities(tbl, visibleRows(ix)) | 
		
	
		
			
				|  |  |  |  |             setCurrPage(tbl, ix) | 
		
	
		
			
				|  |  |  |  |         function changePage(ctx, ix) { | 
		
	
		
			
				|  |  |  |  |             toggleVisibilities(ctx.tbl, visibleRows(ix)) | 
		
	
		
			
				|  |  |  |  |             setCurrPage(ctx, ix) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function enablePagination(on) { | 
		
	
		
			
				|  |  |  |  |             document.querySelectorAll('.pg-btn').forEach(function(btn) { | 
		
	
		
			
				|  |  |  |  |         function enablePagination(ctx, on) { | 
		
	
		
			
				|  |  |  |  |             [...ctx.nextBtns, ...ctx.prevBtns].forEach(function (btn) { | 
		
	
		
			
				|  |  |  |  |                 btn.disabled = !on | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |             document.querySelectorAll('.row-info .page').forEach(function(elem) { | 
		
	
		
			
				|  |  |  |  |             ctx.pageLbls.forEach(function (elem) { | 
		
	
		
			
				|  |  |  |  |                 elem.style.display = on ? 'inline' : 'none' | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function prevButton(tbl) { | 
		
	
		
			
				|  |  |  |  |         function prevButton() { | 
		
	
		
			
				|  |  |  |  |             const btn = document.createElement('button') | 
		
	
		
			
				|  |  |  |  |             btn.classList.add('prev') | 
		
	
		
			
				|  |  |  |  |             btn.classList.add('pg-btn') | 
		
	
		
			
				|  |  |  |  |             btn.innerText = 'Prev' | 
		
	
		
			
				|  |  |  |  |             btn.addEventListener('click', function () { | 
		
	
		
			
				|  |  |  |  |                 const page = tbl.getAttribute('data-page') * 1 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (page > 0) { | 
		
	
		
			
				|  |  |  |  |                     changePage(tbl, page - 1) | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |             return btn; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function nextButton(tbl) { | 
		
	
		
			
				|  |  |  |  |         function nextButton() { | 
		
	
		
			
				|  |  |  |  |             const btn = document.createElement('button') | 
		
	
		
			
				|  |  |  |  |             btn.classList.add('next') | 
		
	
		
			
				|  |  |  |  |             btn.classList.add('pg-btn') | 
		
	
		
			
				|  |  |  |  |             btn.innerText = 'Next' | 
		
	
		
			
				|  |  |  |  |             btn.addEventListener('click', function () { | 
		
	
		
			
				|  |  |  |  |                 const page = tbl.getAttribute('data-page') * 1 | 
		
	
		
			
				|  |  |  |  |                 const lastRowNum = (page + 1) * pageSize | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (lastRowNum < tblRows(tbl).length) { | 
		
	
		
			
				|  |  |  |  |                     changePage(tbl, page + 1) | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |             return btn | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -121,10 +112,10 @@ document.addEventListener('DOMContentLoaded', function () { | 
		
	
		
			
				|  |  |  |  |             rowInfo.classList.add('row-info') | 
		
	
		
			
				|  |  |  |  |             const rows = document.createElement('span') | 
		
	
		
			
				|  |  |  |  |             rows.classList.add('rows') | 
		
	
		
			
				|  |  |  |  |             rows.innerText = 0 | 
		
	
		
			
				|  |  |  |  |             rows.innerText = '0' | 
		
	
		
			
				|  |  |  |  |             const page = document.createElement('span') | 
		
	
		
			
				|  |  |  |  |             page.classList.add('page') | 
		
	
		
			
				|  |  |  |  |             page.innerText = 1 | 
		
	
		
			
				|  |  |  |  |             page.innerText = '1' | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             rowInfo.insertAdjacentElement('afterbegin', rows) | 
		
	
		
			
				|  |  |  |  |             rowInfo.insertAdjacentElement('afterbegin', page) | 
		
	
	
		
			
				
					|  |  |  | @ -132,65 +123,108 @@ document.addEventListener('DOMContentLoaded', function () { | 
		
	
		
			
				|  |  |  |  |             return rowInfo | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function searchBox(tbl) { | 
		
	
		
			
				|  |  |  |  |         function searchBox() { | 
		
	
		
			
				|  |  |  |  |             const input = document.createElement('input') | 
		
	
		
			
				|  |  |  |  |             input.classList.add('search') | 
		
	
		
			
				|  |  |  |  |             input.type = 'search' | 
		
	
		
			
				|  |  |  |  |             input.placeholder = 'search...' | 
		
	
		
			
				|  |  |  |  |             return input | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function onSearch(ctx, evt) { | 
		
	
		
			
				|  |  |  |  |             const term = evt.target.value.toLocaleLowerCase() | 
		
	
		
			
				|  |  |  |  |             if (term.length === 0) { | 
		
	
		
			
				|  |  |  |  |                 changePage(ctx, 0) | 
		
	
		
			
				|  |  |  |  |                 enablePagination(ctx, true) | 
		
	
		
			
				|  |  |  |  |                 return | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             enablePagination(ctx, false) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             const contents = tblRows(tbl).map(function(row) { | 
		
	
		
			
				|  |  |  |  |                 return Array.from(row.cells).reduce(function(carr, cell) { | 
		
	
		
			
				|  |  |  |  |             const contents = tblRows(ctx.tbl).map(function (row) { | 
		
	
		
			
				|  |  |  |  |                 return Array.from(row.cells).reduce(function (carr, cell) { | 
		
	
		
			
				|  |  |  |  |                     return carr + cell.innerText.toLocaleLowerCase() | 
		
	
		
			
				|  |  |  |  |                 }, "") | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             input.addEventListener('input', function(evt, a) { | 
		
	
		
			
				|  |  |  |  |                 const term = evt.target.value.toLocaleLowerCase() | 
		
	
		
			
				|  |  |  |  |                 if (term.length === 0) { | 
		
	
		
			
				|  |  |  |  |                     changePage(tbl, 0) | 
		
	
		
			
				|  |  |  |  |                     enablePagination(true) | 
		
	
		
			
				|  |  |  |  |                     return | 
		
	
		
			
				|  |  |  |  |             const ixs = [] | 
		
	
		
			
				|  |  |  |  |             contents.forEach(function (rowContent, ix) { | 
		
	
		
			
				|  |  |  |  |                 if (rowContent.match(term)) { | 
		
	
		
			
				|  |  |  |  |                     ixs.push(ix) | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 enablePagination(false) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 const ixs = [] | 
		
	
		
			
				|  |  |  |  |                 contents.forEach(function(rowContent, ix) { | 
		
	
		
			
				|  |  |  |  |                     if (rowContent.match(term)) { | 
		
	
		
			
				|  |  |  |  |                         ixs.push(ix) | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 }) | 
		
	
		
			
				|  |  |  |  |                 document.querySelectorAll('.row-info .rows').forEach(function(elem) { | 
		
	
		
			
				|  |  |  |  |                     elem.innerText = ixs.length | 
		
	
		
			
				|  |  |  |  |                 }) | 
		
	
		
			
				|  |  |  |  |                 toggleVisibilities(tbl, ixs) | 
		
	
		
			
				|  |  |  |  |             ctx.rowsLbls.forEach(function (elem) { | 
		
	
		
			
				|  |  |  |  |                 elem.innerText = ixs.length | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |             return input | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             toggleVisibilities(ctx.tbl, ixs) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function onPrevClick(ctx) { | 
		
	
		
			
				|  |  |  |  |             const page = ctx.tbl.getAttribute('data-page') * 1 | 
		
	
		
			
				|  |  |  |  |             if (page > 0) { | 
		
	
		
			
				|  |  |  |  |                 changePage(ctx, page - 1) | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function onNextClick(ctx) { | 
		
	
		
			
				|  |  |  |  |             const page = ctx.tbl.getAttribute('data-page') * 1 | 
		
	
		
			
				|  |  |  |  |             const lastRowNum = (page + 1) * pageSize | 
		
	
		
			
				|  |  |  |  |             if (lastRowNum < tblRows(ctx.tbl).length) { | 
		
	
		
			
				|  |  |  |  |                 changePage(ctx, page + 1) | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function buildContext(tbl) { | 
		
	
		
			
				|  |  |  |  |             const currPage1 = currPage() | 
		
	
		
			
				|  |  |  |  |             const currPage2 = currPage() | 
		
	
		
			
				|  |  |  |  |             const ctx = { | 
		
	
		
			
				|  |  |  |  |                 tbl: tbl, | 
		
	
		
			
				|  |  |  |  |                 currPages: [currPage1, currPage2], | 
		
	
		
			
				|  |  |  |  |                 pageLbls: [currPage1.children[0], currPage2.children[0]], | 
		
	
		
			
				|  |  |  |  |                 rowsLbls: [currPage1.children[1], currPage2.children[1]], | 
		
	
		
			
				|  |  |  |  |                 searchBox: searchBox(), | 
		
	
		
			
				|  |  |  |  |                 prevBtns: [prevButton(), prevButton()], | 
		
	
		
			
				|  |  |  |  |                 nextBtns: [nextButton(), nextButton()] | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             ctx.searchBox.addEventListener('input', partial11(onSearch, ctx)) | 
		
	
		
			
				|  |  |  |  |             ctx.prevBtns.forEach(function (btn) { | 
		
	
		
			
				|  |  |  |  |                 btn.addEventListener('click', partial11(onPrevClick, ctx)) | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  |             ctx.nextBtns.forEach(function (btn) { | 
		
	
		
			
				|  |  |  |  |                 btn.addEventListener('click', partial11(onNextClick, ctx)) | 
		
	
		
			
				|  |  |  |  |             }) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             return ctx | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         function addToolbar(tbl) { | 
		
	
		
			
				|  |  |  |  |             const ctx = buildContext(tbl) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             const toolbarTop = document.createElement('section') | 
		
	
		
			
				|  |  |  |  |             toolbarTop.classList.add('tbl-toolbar') | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', currPage()) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', searchBox(tbl)) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', prevButton(tbl)) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', nextButton(tbl)) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', ctx.currPages[0]) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', ctx.searchBox) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', ctx.prevBtns[0]) | 
		
	
		
			
				|  |  |  |  |             toolbarTop.insertAdjacentElement('beforeend', ctx.nextBtns[0]) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             const toolbarBottom = document.createElement('section') | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.classList.add('tbl-toolbar') | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', currPage()) | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', prevButton(tbl)) | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', nextButton(tbl)) | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', ctx.currPages[1]) | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', ctx.prevBtns[1]) | 
		
	
		
			
				|  |  |  |  |             toolbarBottom.insertAdjacentElement('beforeend', ctx.nextBtns[1]) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             tbl.insertAdjacentElement('afterend', toolbarBottom) | 
		
	
		
			
				|  |  |  |  |             tbl.insertAdjacentElement('beforebegin', toolbarTop) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             return ctx | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         document.querySelectorAll('table').forEach(function (tbl) { | 
		
	
		
			
				|  |  |  |  |             toggleVisibilities(tbl, visibleRows(0)) | 
		
	
		
			
				|  |  |  |  |             tbl.setAttribute('data-page', 0) | 
		
	
		
			
				|  |  |  |  |             addToolbar(tbl) | 
		
	
		
			
				|  |  |  |  |             setCurrPage(tbl, 0) | 
		
	
		
			
				|  |  |  |  |             const ctx = addToolbar(tbl) | 
		
	
		
			
				|  |  |  |  |             changePage(ctx, 0) | 
		
	
		
			
				|  |  |  |  |         }) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |