diff options
| author | rr- | 2017-02-09 00:48:06 +0100 |
|---|---|---|
| committer | rr- | 2017-02-09 22:40:00 +0100 |
| commit | fdad08e176b52f1b47930a5e9b22116c70c542a8 (patch) | |
| tree | 8e5985a15278d8d4245dffc4a3ac50e2fdc0b6e8 /client/js/views/endless_page_view.js | |
| parent | ba7ca0cd8727b5397729983d052636637f36dd59 (diff) | |
server: use index-based paging (#123)
Diffstat (limited to 'client/js/views/endless_page_view.js')
| -rw-r--r-- | client/js/views/endless_page_view.js | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/client/js/views/endless_page_view.js b/client/js/views/endless_page_view.js index c70d417..20f3b97 100644 --- a/client/js/views/endless_page_view.js +++ b/client/js/views/endless_page_view.js @@ -21,16 +21,19 @@ class EndlessPageView { views.emptyContent(this._pagesHolderNode); this.threshold = window.innerHeight / 3; - this.minPageShown = null; - this.maxPageShown = null; - this.totalPages = null; - this.currentPage = null; + this.minOffsetShown = null; + this.maxOffsetShown = null; + this.totalRecords = null; + this.currentOffset = 0; - this._loadPage(ctx, ctx.parameters.page, true).then(pageNode => { - if (ctx.parameters.page !== 1) { - pageNode.scrollIntoView(); - } - }); + const offset = parseInt(ctx.parameters.offset || 0); + const limit = parseInt(ctx.parameters.limit || ctx.defaultLimit); + this._loadPage(ctx, offset, limit, true) + .then(pageNode => { + if (offset !== 0) { + pageNode.scrollIntoView(); + } + }); this._probePageLoad(ctx); views.monitorNodeRemoval(this._pagesHolderNode, () => this._destroy()); @@ -75,42 +78,45 @@ class EndlessPageView { if (!topPageNode) { return; } - let topPageNumber = parseInt(topPageNode.getAttribute('data-page')); - if (topPageNumber !== this.currentPage) { + let topOffset = parseInt(topPageNode.getAttribute('data-offset')); + let topLimit = parseInt(topPageNode.getAttribute('data-limit')); + if (topOffset !== this.currentOffset) { router.replace( - ctx.getClientUrlForPage(topPageNumber), + ctx.getClientUrlForPage( + topOffset, + topLimit === ctx.defaultLimit ? null : topLimit), ctx.state, false); - this.currentPage = topPageNumber; + this.currentOffset = topOffset; } - if (this.totalPages === null) { + if (this.totalRecords === null) { return; } let scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; - if (this.minPageShown > 1 && window.scrollY < this.threshold) { - this._loadPage(ctx, this.minPageShown - 1, false); - } else if (this.maxPageShown < this.totalPages && + if (this.minOffsetShown > 0 && window.scrollY < this.threshold) { + this._loadPage( + ctx, this.minOffsetShown - topLimit, topLimit, false); + } else if (this.maxOffsetShown < this.totalRecords && window.scrollY + this.threshold > scrollHeight) { - this._loadPage(ctx, this.maxPageShown + 1, true); + this._loadPage( + ctx, this.maxOffsetShown, topLimit, true); } } - _loadPage(ctx, pageNumber, append) { + _loadPage(ctx, offset, limit, append) { this._working++; return new Promise((resolve, reject) => { - ctx.requestPage(pageNumber).then(response => { + ctx.requestPage(offset, limit).then(response => { if (!this._active) { this._working--; return Promise.reject(); } - this.totalPages = Math.ceil(response.total / response.pageSize); window.requestAnimationFrame(() => { - let pageNode = this._renderPage( - ctx, pageNumber, append, response); + let pageNode = this._renderPage(ctx, append, response); this._working--; resolve(pageNode); }); @@ -122,33 +128,40 @@ class EndlessPageView { }); } - _renderPage(ctx, pageNumber, append, response) { + _renderPage(ctx, append, response) { let pageNode = null; if (response.total) { pageNode = pageTemplate({ - page: pageNumber, - totalPages: this.totalPages, + totalPages: Math.ceil(response.total / response.limit), + page: Math.ceil( + (response.offset + response.limit) / response.limit), + }); + pageNode.setAttribute('data-offset', response.offset); + pageNode.setAttribute('data-limit', response.limit); + + ctx.pageRenderer({ + parameters: ctx.parameters, + response: response, + hostNode: pageNode.querySelector('.page-content-holder'), }); - pageNode.setAttribute('data-page', pageNumber); - Object.assign(ctx.pageContext, response); - ctx.pageContext.hostNode = pageNode.querySelector( - '.page-content-holder'); - ctx.pageRenderer(ctx.pageContext); + this.totalRecords = response.total; - if (pageNumber < this.minPageShown || - this.minPageShown === null) { - this.minPageShown = pageNumber; + if (response.offset < this.minOffsetShown || + this.minOffsetShown === null) { + this.minOffsetShown = response.offset; } - if (pageNumber > this.maxPageShown || - this.maxPageShown === null) { - this.maxPageShown = pageNumber; + if (response.offset + response.results.length + > this.maxOffsetShown || + this.maxOffsetShown === null) { + this.maxOffsetShown = + response.offset + response.results.length; } if (append) { this._pagesHolderNode.appendChild(pageNode); - if (!this._init && pageNumber !== 1) { + if (!this._init && response.offset > 0) { window.scroll(0, pageNode.getBoundingClientRect().top); } } else { @@ -158,7 +171,7 @@ class EndlessPageView { window.scrollX, window.scrollY + pageNode.offsetHeight); } - } else if (response.total <= (pageNumber - 1) * response.pageSize) { + } else if (!response.results.length) { this.showInfo('No data to show'); } |