import { makeEl, clearEl } from "./dom";
class SimplePaginator {
constructor(element) {
this.element = element;
}
attach(pageCallback) {
this.element.addEventListener('click', evt => {
if (evt.target && evt.target.classList.contains('paginator__button')) {
pageCallback(+evt.target.dataset.page);
}
});
}
update(totalRecords, perPage, currentPage) {
clearEl(this.element);
/* First and last page in existence */
const firstPage = 0;
const lastPage = Math.ceil(totalRecords / perPage); // ish?
const numPagesToShow = 3;
/* First and last page the main paginator will show */
const firstPageShow = (currentPage - numPagesToShow < 0) ? currentPage : currentPage - numPagesToShow;
const lastPageShow = (firstPageShow + numPagesToShow) > lastPage ? lastPage : (firstPageShow + numPagesToShow * 2);
/* Whether to show the first and last pages in existence at the ends of the paginator */
const showFirstPage = (Math.abs(firstPage - currentPage)) > (numPagesToShow * 2);
const showLastPage = (Math.abs(lastPage - currentPage)) > (numPagesToShow * 2);
/* Previous button */
this.element.appendChild(makeEl(
`Previous`
));
/* First page button */
if (showFirstPage) {
this.element.appendChild(makeEl(
`${firstPage}`
));
this.element.appendChild(makeEl(`…`));
}
/* "window" buttons */
for (let i = firstPageShow; i <= lastPageShow; i++) {
this.element.appendChild(makeEl(
`${i}`
));
}
/* Last page button */
if (showLastPage) {
this.element.appendChild(makeEl(`…`));
this.element.appendChild(makeEl(
`${lastPage}`
));
}
/* Next button */
this.element.appendChild(makeEl(
`Next`
));
}
}
class DataTable {
constructor(element, options) {
this.element = element;
this.container = element.parentElement;
this.options = options;
this.ajaxCallback = options.ajaxCallback;
this.data = [];
this.totalRecords = -1;
this.perPage = 10;
this.currentPage = 0;
this.paginator = new SimplePaginator(this.container.querySelector('.paginator'));
}
attach() {
this.paginator.attach(this._updatePage.bind(this));
this._loadEntries();
}
/* Load the requested data from the server, and when done, update the DOM. */
_loadEntries() {
new Promise(this.ajaxCallback)
.then(this._updateEntries.bind(this));
}
/* Update the DOM to reflect the current state of the data we have loaded */
_updateEntries(data) {
this.data = data.data;
this.totalRecords = this.data.length;
const bodyElement = this.element.querySelector('tbody');
clearEl(bodyElement);
const firstIndex = (this.perPage * this.currentPage);
const lastIndex = (firstIndex + this.perPage) > this.totalRecords ? this.totalRecords : (firstIndex + this.perPage);
for (let i = firstIndex; i < lastIndex; i++) {
const rowElem = makeEl(this.options.rowCallback(this.data[i]));
rowElem.classList.add(i % 2 === 0 ? 'odd' : 'even');
bodyElement.appendChild(rowElem);
}
this.paginator.update(this.totalRecords, this.perPage, this.currentPage);
}
_updatePage(n) {
this.currentPage = n;
this.paginator.update(this.totalRecords, this.perPage, this.currentPage);
this._updateEntries({data: this.data});
}
_updateSort(field, direction) {
}
}
export { DataTable };