Extracted pager from paged collection presenter
This commit is contained in:
parent
c124f89b8b
commit
14325b4338
6 changed files with 189 additions and 98 deletions
1
TODO
1
TODO
|
@ -26,7 +26,6 @@ everything related to posts:
|
|||
|
||||
- single post view
|
||||
- previous and next post (difficult)
|
||||
- extract Pager from PagedCollectionPresenter
|
||||
- rename PagedCollectionPresenter to PagerPresenter
|
||||
- remember last search
|
||||
- take care of pages
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<script type="text/javascript" src="/js/Auth.js"></script>
|
||||
<script type="text/javascript" src="/js/Util.js"></script>
|
||||
<script type="text/javascript" src="/js/Keyboard.js"></script>
|
||||
<script type="text/javascript" src="/js/Pager.js"></script>
|
||||
<script type="text/javascript" src="/js/BrowsingSettings.js"></script>
|
||||
<script type="text/javascript" src="/js/Controls/FileDropper.js"></script>
|
||||
<script type="text/javascript" src="/js/Controls/TagInput.js"></script>
|
||||
|
|
109
public_html/js/Pager.js
Normal file
109
public_html/js/Pager.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
var App = App || {};
|
||||
|
||||
App.Pager = function(
|
||||
_,
|
||||
promise,
|
||||
api) {
|
||||
|
||||
var totalPages;
|
||||
var pageNumber;
|
||||
var searchParams;
|
||||
var url;
|
||||
|
||||
function init(args) {
|
||||
url = args.url;
|
||||
|
||||
setSearchParams(args.searchParams);
|
||||
if (typeof(args.page) !== 'undefined') {
|
||||
setPage(args.page);
|
||||
} else {
|
||||
setPage(1);
|
||||
}
|
||||
}
|
||||
|
||||
function getPage() {
|
||||
return pageNumber;
|
||||
}
|
||||
|
||||
function prevPage() {
|
||||
if (pageNumber > 1) {
|
||||
setPage(pageNumber - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
if (pageNumber < totalPages) {
|
||||
setPage(pageNumber + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function setPage(newPageNumber) {
|
||||
pageNumber = parseInt(newPageNumber);
|
||||
if (!pageNumber || isNaN(pageNumber)) {
|
||||
throw new Error('Trying to set page to a non-number (' + newPageNumber + ')');
|
||||
}
|
||||
}
|
||||
|
||||
function getSearchParams() {
|
||||
return searchParams;
|
||||
}
|
||||
|
||||
function setSearchParams(newSearchParams) {
|
||||
setPage(1);
|
||||
searchParams = newSearchParams;
|
||||
}
|
||||
|
||||
function retrieve() {
|
||||
return promise.make(function(resolve, reject) {
|
||||
promise.wait(
|
||||
api.get(url, _.extend({}, searchParams, {page: pageNumber})))
|
||||
.then(function(response) {
|
||||
var pageSize = response.json.pageSize;
|
||||
var totalRecords = response.json.totalRecords;
|
||||
totalPages = Math.ceil(totalRecords / pageSize);
|
||||
|
||||
resolve({
|
||||
entities: response.json.data,
|
||||
totalRecords: totalRecords});
|
||||
|
||||
}).fail(function(response) {
|
||||
reject(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getVisiblePages() {
|
||||
var pages = [1, totalPages || 1];
|
||||
var pagesAroundCurrent = 2;
|
||||
for (var i = -pagesAroundCurrent; i <= pagesAroundCurrent; i ++) {
|
||||
if (pageNumber + i >= 1 && pageNumber + i <= totalPages) {
|
||||
pages.push(pageNumber + i);
|
||||
}
|
||||
}
|
||||
if (pageNumber - pagesAroundCurrent - 1 === 2) {
|
||||
pages.push(2);
|
||||
}
|
||||
if (pageNumber + pagesAroundCurrent + 1 === totalPages - 1) {
|
||||
pages.push(totalPages - 1);
|
||||
}
|
||||
|
||||
return pages.sort(function(a, b) { return a - b; }).filter(function(item, pos) {
|
||||
return !pos || item !== pages[pos - 1];
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
getPage: getPage,
|
||||
prevPage: prevPage,
|
||||
nextPage: nextPage,
|
||||
setPage: setPage,
|
||||
getSearchParams: getSearchParams,
|
||||
setSearchParams: setSearchParams,
|
||||
retrieve: retrieve,
|
||||
getVisiblePages: getVisiblePages,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.register('pager', ['_', 'promise', 'api'], App.Pager);
|
|
@ -9,6 +9,7 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
api,
|
||||
keyboard,
|
||||
router,
|
||||
pager,
|
||||
presenterManager,
|
||||
browsingSettings) {
|
||||
|
||||
|
@ -18,24 +19,22 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
var endlessScroll = browsingSettings.getSettings().endlessScroll;
|
||||
var scrollInterval;
|
||||
var template;
|
||||
var totalPages;
|
||||
var forceClear = false;
|
||||
|
||||
var pageNumber;
|
||||
var searchParams;
|
||||
var baseUri;
|
||||
var backendUri;
|
||||
var updateCallback;
|
||||
var failCallback;
|
||||
|
||||
function init(args, loaded) {
|
||||
baseUri = args.baseUri;
|
||||
updateCallback = args.updateCallback;
|
||||
failCallback = args.failCallback;
|
||||
|
||||
$target = args.$target;
|
||||
targetContent = jQuery(args.$target).html();
|
||||
|
||||
baseUri = args.baseUri;
|
||||
backendUri = args.backendUri;
|
||||
updateCallback = args.updateCallback;
|
||||
failCallback = args.failCallback;
|
||||
pager.init({url: args.backendUri});
|
||||
pager.setSearchParams(args.searchParams);
|
||||
|
||||
promise.wait(util.promiseTemplate('pager'))
|
||||
.then(function(html) {
|
||||
|
@ -46,12 +45,12 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
forceClear = !_.isEqual(args.searchParams, searchParams) || parseInt(args.page) !== pageNumber + 1;
|
||||
forceClear = !_.isEqual(args.searchParams, pager.getSearchParams()) || parseInt(args.page) !== pager.getPage();
|
||||
|
||||
searchParams = args.searchParams;
|
||||
pageNumber = parseInt(args.page) || 1;
|
||||
pager.setSearchParams(args.searchParams);
|
||||
pager.setPage(args.page || 1);
|
||||
|
||||
softChangePage(pageNumber)
|
||||
retrieve()
|
||||
.then(loaded)
|
||||
.fail(loaded);
|
||||
|
||||
|
@ -62,29 +61,46 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
}
|
||||
|
||||
function prevPage() {
|
||||
if (pageNumber > 1) {
|
||||
changePage(pageNumber - 1);
|
||||
}
|
||||
pager.prevPage();
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
if (pageNumber < totalPages) {
|
||||
changePage(pageNumber + 1);
|
||||
}
|
||||
pager.nextPage();
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function nextPageInplace() {
|
||||
if (pageNumber < totalPages) {
|
||||
changePageInplace(pageNumber + 1);
|
||||
}
|
||||
pager.nextPage();
|
||||
syncUrlInplace();
|
||||
}
|
||||
|
||||
function changePageInplace(newPageNumber) {
|
||||
router.navigateInplace(getPageChangeLink(newPageNumber));
|
||||
function setPage(newPage) {
|
||||
pager.setPage(newPage);
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function changePage(newPageNumber) {
|
||||
router.navigate(getPageChangeLink(newPageNumber));
|
||||
function setSearchParams(newSearchParams) {
|
||||
clearContent();
|
||||
pager.setSearchParams(newSearchParams);
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return util.compileComplexRouteArgs(
|
||||
baseUri,
|
||||
_.extend(
|
||||
{},
|
||||
pager.getSearchParams(),
|
||||
{page: pager.getPage()}));
|
||||
}
|
||||
|
||||
function syncUrl() {
|
||||
router.navigate(getUrl());
|
||||
}
|
||||
|
||||
function syncUrlInplace() {
|
||||
router.navigateInplace(getUrl());
|
||||
}
|
||||
|
||||
function showSpinner() {
|
||||
|
@ -103,40 +119,34 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
}
|
||||
}
|
||||
|
||||
function softChangePage(newPageNumber) {
|
||||
pageNumber = newPageNumber;
|
||||
|
||||
function retrieve() {
|
||||
showSpinner();
|
||||
|
||||
return promise.make(function(resolve, reject) {
|
||||
promise.wait(
|
||||
api.get(backendUri, _.extend({}, searchParams, {page: pageNumber})))
|
||||
pager.retrieve()
|
||||
.then(function(response) {
|
||||
resolve(response);
|
||||
var pageSize = response.json.pageSize;
|
||||
var totalRecords = response.json.totalRecords;
|
||||
totalPages = Math.ceil(totalRecords / pageSize);
|
||||
|
||||
updateCallback({
|
||||
entities: response.json.data,
|
||||
totalRecords: totalRecords},
|
||||
forceClear || !endlessScroll);
|
||||
updateCallback(response, forceClear || !endlessScroll);
|
||||
forceClear = false;
|
||||
|
||||
refreshPageList();
|
||||
hideSpinner();
|
||||
attachNextPageLoader();
|
||||
resolve();
|
||||
}).fail(function(response) {
|
||||
reject(response);
|
||||
if (typeof(failCallback) !== 'undefined') {
|
||||
failCallback(response);
|
||||
} else {
|
||||
console.log(new Error(response.json && response.json.error || response));
|
||||
}
|
||||
reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clearContent() {
|
||||
updateCallback({entities: [], totalRecords: 0}, true);
|
||||
}
|
||||
|
||||
function attachNextPageLoader() {
|
||||
if (!endlessScroll) {
|
||||
return;
|
||||
|
@ -154,10 +164,7 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
}
|
||||
|
||||
function refreshPageList() {
|
||||
if (typeof(totalPages) === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var pages = getVisiblePages();
|
||||
var pages = pager.getVisiblePages();
|
||||
$pageList.empty();
|
||||
var lastPage = 0;
|
||||
_.each(pages, function(page) {
|
||||
|
@ -167,10 +174,13 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
lastPage = page;
|
||||
|
||||
var $a = jQuery('<a/>');
|
||||
$a.click(function() {
|
||||
setPage(page);
|
||||
});
|
||||
$a.addClass('big-button');
|
||||
$a.attr('href', getPageChangeLink(page));
|
||||
$a.attr('href', '#');
|
||||
$a.text(page);
|
||||
if (page === pageNumber) {
|
||||
if (page === pager.getPage()) {
|
||||
$a.addClass('active');
|
||||
}
|
||||
var $li = jQuery('<li/>');
|
||||
|
@ -189,42 +199,13 @@ App.Presenters.PagedCollectionPresenter = function(
|
|||
}
|
||||
}
|
||||
|
||||
function getVisiblePages() {
|
||||
var pages = [1, totalPages || 1];
|
||||
var pagesAroundCurrent = 2;
|
||||
for (var i = -pagesAroundCurrent; i <= pagesAroundCurrent; i ++) {
|
||||
if (pageNumber + i >= 1 && pageNumber + i <= totalPages) {
|
||||
pages.push(pageNumber + i);
|
||||
}
|
||||
}
|
||||
if (pageNumber - pagesAroundCurrent - 1 === 2) {
|
||||
pages.push(2);
|
||||
}
|
||||
if (pageNumber + pagesAroundCurrent + 1 === totalPages - 1) {
|
||||
pages.push(totalPages - 1);
|
||||
}
|
||||
|
||||
return pages.sort(function(a, b) { return a - b; }).filter(function(item, pos) {
|
||||
return !pos || item !== pages[pos - 1];
|
||||
});
|
||||
}
|
||||
|
||||
function getSearchChangeLink(newSearchParams) {
|
||||
return util.compileComplexRouteArgs(baseUri, _.extend({}, searchParams, newSearchParams, {page: 1}));
|
||||
}
|
||||
|
||||
function getPageChangeLink(newPageNumber) {
|
||||
return util.compileComplexRouteArgs(baseUri, _.extend({}, searchParams, {page: newPageNumber}));
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
reinit: reinit,
|
||||
changePage: changePage,
|
||||
getSearchChangeLink: getSearchChangeLink,
|
||||
getPageChangeLink: getPageChangeLink
|
||||
setPage: setPage,
|
||||
setSearchParams: setSearchParams,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.register('pagedCollectionPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'keyboard', 'router', 'presenterManager', 'browsingSettings'], App.Presenters.PagedCollectionPresenter);
|
||||
App.DI.register('pagedCollectionPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'keyboard', 'router', 'pager', 'presenterManager', 'browsingSettings'], App.Presenters.PagedCollectionPresenter);
|
||||
|
|
|
@ -7,7 +7,6 @@ App.Presenters.UserListPresenter = function(
|
|||
util,
|
||||
promise,
|
||||
auth,
|
||||
router,
|
||||
pagedCollectionPresenter,
|
||||
topNavigationPresenter,
|
||||
messagePresenter) {
|
||||
|
@ -56,7 +55,10 @@ App.Presenters.UserListPresenter = function(
|
|||
searchArgs.order = searchArgs.order || 'name,asc';
|
||||
updateActiveOrder(searchArgs.order);
|
||||
|
||||
pagedCollectionPresenter.reinit({page: searchArgs.page, searchParams: {order: searchArgs.order}});
|
||||
pagedCollectionPresenter.reinit({
|
||||
page: searchArgs.page,
|
||||
searchParams: {
|
||||
order: searchArgs.order}});
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
@ -91,7 +93,7 @@ App.Presenters.UserListPresenter = function(
|
|||
e.preventDefault();
|
||||
var $orderLink = jQuery(this);
|
||||
var activeSearchOrder = $orderLink.attr('data-order');
|
||||
router.navigate(pagedCollectionPresenter.getSearchChangeLink({order: activeSearchOrder}));
|
||||
pagedCollectionPresenter.setSearchParams({order: activeSearchOrder});
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -102,4 +104,4 @@ App.Presenters.UserListPresenter = function(
|
|||
|
||||
};
|
||||
|
||||
App.DI.register('userListPresenter', ['_', 'jQuery', 'util', 'promise', 'auth', 'router', 'pagedCollectionPresenter', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.UserListPresenter);
|
||||
App.DI.register('userListPresenter', ['_', 'jQuery', 'util', 'promise', 'auth', 'pagedCollectionPresenter', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.UserListPresenter);
|
||||
|
|
|
@ -42,10 +42,9 @@ App.Util = function(_, jQuery, promise) {
|
|||
function compileComplexRouteArgs(baseUri, args) {
|
||||
var result = baseUri + '/';
|
||||
_.each(args, function(v, k) {
|
||||
if (typeof(v) === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (typeof(v) !== 'undefined') {
|
||||
result += k + '=' + v + ';';
|
||||
}
|
||||
});
|
||||
result = result.slice(0, -1);
|
||||
return result;
|
||||
|
|
Loading…
Reference in a new issue