133 lines · 3.1 KB · JavaScript
RawDownload
app.views.PaginatedList = class PaginatedList extends app.View {  static PER_PAGE = app.config.max_results;   constructor(data) {    super();    this.data = data;    this.constructor.events = this.constructor.events || {};    if (this.constructor.events.click == null) {      this.constructor.events.click = "onClick";    }  }   renderPaginated() {    this.page = 0;     if (this.totalPages() > 1) {      this.paginateNext();    } else {      this.html(this.renderAll());    }  }   // render: (dataSlice) -> implemented by subclass   renderAll() {    return this.render(this.data);  }   renderPage(page) {    return this.render(      this.data.slice(        (page - 1) * PaginatedList.PER_PAGE,        page * PaginatedList.PER_PAGE,      ),    );  }   renderPageLink(count) {    return this.tmpl("sidebarPageLink", count);  }   renderPrevLink(page) {    return this.renderPageLink((page - 1) * PaginatedList.PER_PAGE);  }   renderNextLink(page) {    return this.renderPageLink(      this.data.length - page * PaginatedList.PER_PAGE,    );  }   totalPages() {    return Math.ceil(this.data.length / PaginatedList.PER_PAGE);  }   paginate(link) {    $.lockScroll(link.nextSibling || link.previousSibling, () => {      $.batchUpdate(this.el, () => {        if (link.nextSibling) {          this.paginatePrev(link);        } else {          this.paginateNext(link);        }      });    });  }   paginateNext() {    if (this.el.lastChild) {      this.remove(this.el.lastChild);    } // remove link    if (this.page >= 2) {      this.hideTopPage();    } // keep previous page into view    this.page++;    this.append(this.renderPage(this.page));    if (this.page < this.totalPages()) {      this.append(this.renderNextLink(this.page));    }  }   paginatePrev() {    this.remove(this.el.firstChild); // remove link    this.hideBottomPage();    this.page--;    this.prepend(this.renderPage(this.page - 1)); // previous page is offset by one    if (this.page >= 3) {      this.prepend(this.renderPrevLink(this.page - 1));    }  }   paginateTo(object) {    const index = this.data.indexOf(object);    if (index >= PaginatedList.PER_PAGE) {      for (        let i = 0, end = Math.floor(index / PaginatedList.PER_PAGE);        i < end;        i++      ) {        this.paginateNext();      }    }  }   hideTopPage() {    const n =      this.page <= 2 ? PaginatedList.PER_PAGE : PaginatedList.PER_PAGE + 1; // remove link    for (let i = 0, end = n; i < end; i++) {      this.remove(this.el.firstChild);    }    this.prepend(this.renderPrevLink(this.page));  }   hideBottomPage() {    const n =      this.page === this.totalPages()        ? this.data.length % PaginatedList.PER_PAGE || PaginatedList.PER_PAGE        : PaginatedList.PER_PAGE + 1; // remove link    for (let i = 0, end = n; i < end; i++) {      this.remove(this.el.lastChild);    }    this.append(this.renderNextLink(this.page - 1));  }   onClick(event) {    const target = $.eventTarget(event);    if (target.tagName === "SPAN") {      // link      $.stopEvent(event);      this.paginate(target);    }  }};