summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2014-08-09 09:20:44 -0400
committerDavid Thompson <dthompson2@worcester.edu>2014-08-09 09:20:44 -0400
commit6d5af995d9c6294a164e0b0056950731be948866 (patch)
tree84ed7ba1094dd579cdcddafd12b8e3b121433b57
parentcd21ea5d613b4174f1f29cad3da201c62ff9c247 (diff)
Add pagination.
* js/guix-packages.js: (guix.chunk): New function. (guix.paginate): New function. (guix.controller.pages, guix.controller.currentPageIndex, guix.controller.pageSize): New variables. (guix.controller.currentPage, guix.controller.isFirstPage, guix.controller.isLastPage, guix.controller.isCurrentPage, guix.controller.packageCount): New functions. (guix.controller.doSearch): Paginate. (guix.view): Render pagination UI.
-rw-r--r--js/guix-packages.js102
1 files changed, 95 insertions, 7 deletions
diff --git a/js/guix-packages.js b/js/guix-packages.js
index d4e975a..7ab30a0 100644
--- a/js/guix-packages.js
+++ b/js/guix-packages.js
@@ -17,25 +17,71 @@
var guix = {};
+guix.chunk = function(array, size) {
+ return array.reduce(function(memo, value, i) {
+ var currentSlice = _(memo).last();
+
+ if(i / size < memo.length) {
+ currentSlice.push(value);
+ } else {
+ memo.push([value]);
+ }
+
+ return memo;
+ }, []);
+};
+
+guix.paginate = function(array, pageSize) {
+ return guix.chunk(array, pageSize);
+};
+
guix.Packages = function() {
return m.request({ method: "GET", url: "packages.json" });
};
guix.controller = function() {
+ var self = this;
+
this.packages = guix.Packages();
- this.visiblePackages = m.prop([]);
+ this.pages = m.prop([]);
+ this.currentPageIndex = 0;
+ this.pageSize = 20;
this.searchTerm = m.prop("");
// All packages are visible initially
- this.packages.then(this.visiblePackages);
+ this.packages.then(function(packages) {
+ self.pages(guix.paginate(packages, self.pageSize));
+ });
+
+ this.currentPage = function() {
+ return self.pages()[self.currentPageIndex] || [];
+ };
+
+ this.isFirstPage = function() {
+ return self.currentPageIndex === 0;
+ };
+
+ this.isLastPage = function() {
+ return self.currentPageIndex === self.pages().length - 1;
+ };
+
+ this.isCurrentPage = function(i) {
+ return self.currentPageIndex === i;
+ };
+
+ this.packageCount = function() {
+ return self.pages().reduce(function(memo, page) {
+ return memo + page.length;
+ }, 0);
+ };
this.doSearch = function() {
var regexp = new RegExp(this.searchTerm(), "i");
- this.visiblePackages(this.packages().filter(function(package) {
+ this.pages(guix.paginate(this.packages().filter(function(package) {
return regexp.test(package.name) ||
regexp.test(package.synopsis);
- }));
+ }), self.pageSize));
};
};
@@ -70,10 +116,51 @@ guix.view = function(ctrl) {
}
}
+ function renderPagination() {
+ function renderPage(text, opts) {
+ return m("li", {
+ class: opts.class || "",
+ onclick: opts.onclick
+ }, m("a", { href: "#" }, text));
+ }
+
+ return m("ul.pagination", [
+ // Back page
+ renderPage("«", {
+ class: ctrl.isFirstPage() ? "disabled" : "",
+ onclick: function() {
+ ctrl.currentPageIndex--;
+
+ return false;
+ }
+ })
+ ].concat(ctrl.pages().map(function(page, i) {
+ // Jump to page
+ return renderPage(i + 1, {
+ class: ctrl.isCurrentPage(i) ? "active" : "",
+ onclick: function() {
+ ctrl.currentPageIndex = i;
+
+ return false;
+ }
+ });
+ })).concat([
+ // Forward page
+ renderPage("»", {
+ class: ctrl.isLastPage() ? "disabled" : "",
+ onclick: function() {
+ ctrl.currentPageIndex++;
+
+ return false;
+ }
+ })
+ ]));
+ }
+
return [
m("h2", [
"Packages",
- m("span.badge", ctrl.visiblePackages().length)
+ m("span.badge", ctrl.packageCount())
]),
m("input.form-control", {
type: "text",
@@ -97,7 +184,7 @@ guix.view = function(ctrl) {
])
]),
m("tbody", [
- ctrl.visiblePackages().map(function(package) {
+ ctrl.currentPage().map(function(package) {
return m("tr", [
m("td", renderName(package)),
m("td", package.version),
@@ -107,7 +194,8 @@ guix.view = function(ctrl) {
]);
})
])
- ])
+ ]),
+ renderPagination()
];
};