summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2014-10-16 22:20:04 -0400
committerDavid Thompson <dthompson2@worcester.edu>2014-10-16 22:20:04 -0400
commit8ced57e86f518cecea4fa5c6499ad33459823b77 (patch)
tree333082b73c768c6e1854f613070dc32649bcc8b3
parent93921cef3d2e76b53789140fad7153c025a7c340 (diff)
js: Extract pagination model.
* js/utils.js (guix.clamp): New function. * js/controller/packages.js (guix.packages.controller): Remove 'pages', 'currentPageIndex', and 'pageSize' properties. Add 'pager' prop. Delete 'paginate', 'currentPage', 'isFirstPage', 'isLastPage', and 'isCurrentPage' methods. * js/model/packages.js (guix.packages.Pager): New function. * js/view/packages.js (guix.packages.view): Use new Pager API.
-rw-r--r--js/controller/packages.js47
-rw-r--r--js/model/packages.js54
-rw-r--r--js/utils.js4
-rw-r--r--js/view/packages.js26
4 files changed, 82 insertions, 49 deletions
diff --git a/js/controller/packages.js b/js/controller/packages.js
index db94d72..89f01e9 100644
--- a/js/controller/packages.js
+++ b/js/controller/packages.js
@@ -15,14 +15,19 @@
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
-(function(packages) {
+(function() {
+ var packages = guix.packages;
+
packages.controller = (function() {
+ var PAGE_SIZE = 20;
+
+ function Pager(items) {
+ return new packages.Pager(items, PAGE_SIZE);
+ }
+
function controller() {
var self = this;
- this.pages = m.prop([]);
- this.currentPageIndex = 0;
- this.pageSize = 20;
this.searchTerm = m.prop("");
this.columns = [
{ header: "Name", sortField: "name" },
@@ -43,40 +48,20 @@
}
];
this.sorter = m.prop(new packages.Sorter("name"));
+ this.pager = m.prop(Pager([]));
this.phase = m.prop(packages.PHASE_NONE);
this.selectedPackage = m.prop(null);
this.packages = packages.Packages()
.then(function(packages) {
// All packages are visible initially
- self.pages(self.paginate(packages, self.pageSize));
+ self.pager(Pager(packages));
})
.then(m.redraw);
};
-
- controller.prototype.paginate = function(array, pageSize) {
- return guix.chunk(this.sorter().sort(array), pageSize);
- };
-
- controller.prototype.currentPage = function() {
- return this.pages()[this.currentPageIndex] || [];
- };
-
- controller.prototype.isFirstPage = function() {
- return this.currentPageIndex === 0;
- };
-
- controller.prototype.isLastPage = function() {
- return this.currentPageIndex === this.pages().length - 1;
- };
-
- controller.prototype.isCurrentPage = function(i) {
- return this.currentPageIndex === i;
- };
-
controller.prototype.packageCount = function() {
- return this.pages().reduce(function(memo, page) {
+ return this.pager().pages.reduce(function(memo, page) {
return memo + page.length;
}, 0);
};
@@ -84,12 +69,10 @@
controller.prototype.doSearch = function() {
var regexp = new RegExp(this.searchTerm(), "i");
- this.pages(this.paginate(this.packages().filter(function(package) {
+ this.pager(Pager(this.packages().filter(function(package) {
return regexp.test(package.name) ||
regexp.test(package.synopsis);
- }), this.pageSize));
- // Reset pagination
- this.currentPageIndex = 0;
+ })));
};
controller.prototype.sortBy = function(field) {
@@ -122,4 +105,4 @@
return controller;
})();
-})(guix.packages);
+})();
diff --git a/js/model/packages.js b/js/model/packages.js
index 652d11a..1c61d25 100644
--- a/js/model/packages.js
+++ b/js/model/packages.js
@@ -15,9 +15,11 @@
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
-guix.packages = {};
-(function(packages) {
+
+(function() {
+ var packages = guix.packages = {};
+
packages.Packages = function() {
return m.request({
method: "GET",
@@ -45,9 +47,55 @@ guix.packages = {};
return Sorter;
})();
+ packages.Pager = (function() {
+ function Pager(items, pageSize) {
+ this.pageSize= pageSize;
+ this.pageIndex = 0;
+ this.pages = guix.chunk(items, pageSize);
+ }
+
+ Pager.prototype.currentPage = function() {
+ return this.pages[this.pageIndex];
+ };
+
+ Pager.prototype.pageCount = function() {
+ return this.pages.length;
+ };
+
+ Pager.prototype.isEmpty = function() {
+ return this.pageCount() === 0;
+ };
+
+ Pager.prototype.isFirstPage = function() {
+ return this.pageIndex === 0;
+ };
+
+ Pager.prototype.isLastPage = function() {
+ return this.pageIndex === this.pages.length - 1;
+ };
+
+ Pager.prototype.isCurrentPage = function(i) {
+ return this.pageIndex === i;
+ };
+
+ Pager.prototype.nextPage = function() {
+ this.pageIndex = Math.min(this.pageCount() - 1, this.pageIndex + 1);
+ };
+
+ Pager.prototype.previousPage = function() {
+ this.pageIndex = Math.max(0, this.pageIndex - 1);
+ };
+
+ Pager.prototype.gotoPage = function(page) {
+ this.pageIndex = guix.clamp(page, 0, this.pageCount() -1);
+ };
+
+ return Pager;
+ })();
+
packages.PHASE_NONE = 0;
packages.PHASE_PROMPT = 1;
packages.PHASE_DERIVATION = 2;
packages.PHASE_SUCCESS = 3;
packages.PHASE_ERROR = 4;
-})(guix.packages);
+})();
diff --git a/js/utils.js b/js/utils.js
index b3e4768..c44ee23 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -17,6 +17,10 @@
var guix = {};
+guix.clamp = function(n, min, max) {
+ return Math.max(Math.min(n, max), min);
+};
+
guix.chunk = function(array, size) {
return array.reduce(function(memo, value, i) {
var currentSlice = _(memo).last();
diff --git a/js/view/packages.js b/js/view/packages.js
index e202471..7c55486 100644
--- a/js/view/packages.js
+++ b/js/view/packages.js
@@ -15,7 +15,8 @@
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
-(function(packages) {
+(function() {
+ var packages = guix.packages;
var spinner = m(".spinner-container", m(".spinner"));
packages.view = function(ctrl) {
@@ -75,7 +76,7 @@
])
]),
m("tbody", [
- ctrl.currentPage().map(function(package) {
+ ctrl.pager().currentPage().map(function(package) {
return m("tr", [
m("td", renderName(package)),
m("td", package.version),
@@ -100,30 +101,27 @@
return m("div", m("ul.pagination", [
// Back page
renderPage("«", {
- class: ctrl.isFirstPage() ? "disabled" : "",
+ class: ctrl.pager().isFirstPage() ? "disabled" : "",
onclick: function() {
- ctrl.currentPageIndex--;
-
+ ctrl.pager().previousPage();
return false;
}
})
- ].concat(ctrl.pages().map(function(page, i) {
+ ].concat(ctrl.pager().pages.map(function(page, i) {
// Jump to page
return renderPage(i + 1, {
- class: ctrl.isCurrentPage(i) ? "active" : "",
+ class: ctrl.pager().isCurrentPage(i) ? "active" : "",
onclick: function() {
- ctrl.currentPageIndex = i;
-
+ ctrl.pager().gotoPage(i);
return false;
}
});
})).concat([
// Forward page
renderPage("»", {
- class: ctrl.isLastPage() ? "disabled" : "",
+ class: ctrl.pager().isLastPage() ? "disabled" : "",
onclick: function() {
- ctrl.currentPageIndex++;
-
+ ctrl.pager().nextPage();
return false;
}
})
@@ -239,7 +237,7 @@
return null;
}
- return guix.withLayout(_.isEmpty(ctrl.pages()) ? spinner : [
+ return guix.withLayout(ctrl.pager().isEmpty() ? spinner : [
m("h2", [
"Packages",
m("span.badge", ctrl.packageCount())
@@ -250,4 +248,4 @@
renderPagination()
]);
};
-})(guix.packages);
+})();