diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js
index 98ad4464..b53c3e2e 100644
--- a/www/assets/js/callbacks.js
+++ b/www/assets/js/callbacks.js
@@ -426,25 +426,61 @@ Callbacks = {
if(tbl.children().length > 1) {
$(tbl.children()[1]).remove();
}
- $("#channelranks_pagination").remove();
- if(entries.length > 20) {
- var pag = $("
").addClass("pagination span12")
- .attr("id", "channelranks_pagination")
- .prependTo($("#channelranks"));
- var btns = $("").appendTo(pag);
- for(var i = 0; i < entries.length / 20; i++) {
- var li = $("").appendTo(btns);
- (function(i) {
- $("").attr("href", "javascript:void(0)")
- .text(i+1)
- .click(function() {
- loadChannelRanksPage(i);
- })
- .appendTo(li);
- })(i);
- }
+ var p = tbl.data("paginator");
+ if(p) {
+ p.items = entries;
+ p.loadPage(0);
+ }
+ else {
+ var opts = {
+ preLoadPage: function (p) {
+ tbl.find("tbody").remove();
+ tbl.data("page", p);
+ },
+ generator: function (item, page, index) {
+ var tr = $("
").appendTo(tbl);
+ var name = $(" | ").text(item.name).appendTo(tr);
+ name.addClass(getNameColor(item.rank));
+ var rank = $(" | ").text(item.rank)
+ .css("min-width", "220px")
+ .appendTo(tr);
+ rank.click(function() {
+ if(this.find(".rank-edit").length > 0)
+ return;
+ var r = this.text();
+ this.text("");
+ var edit = $("").attr("type", "text")
+ .attr("placeholder", r)
+ .addClass("rank-edit")
+ .appendTo(this)
+ .focus();
+ if(parseInt(r) >= CLIENT.rank) {
+ edit.attr("disabled", true);
+ }
+ function save() {
+ var r = this.val();
+ var r2 = r;
+ if(r.trim() == "" || parseInt(r) >= CLIENT.rank || parseInt(r) < 1)
+ r = this.attr("placeholder");
+ r = parseInt(r) + "";
+ this.parent().text(r);
+ socket.emit("setChannelRank", {
+ user: item.name,
+ rank: parseInt(r)
+ });
+ }
+ edit.blur(save.bind(edit));
+ edit.keydown(function(ev) {
+ if(ev.keyCode == 13)
+ save.bind(edit)();
+ });
+ }.bind(rank));
+ }
+ };
+ var p = Paginate(entries, opts);
+ p.paginator.insertBefore($("#channelranks table"));
+ tbl.data("paginator", p);
}
- loadChannelRanksPage(0);
},
setChannelRank: function(data) {
@@ -456,7 +492,9 @@ Callbacks = {
}
}
$("#channelranks").data("entries", ents);
- loadChannelRanksPage($("#channelranks").data("page"));
+ $("#channelranks table").data("paginator").loadPage(
+ $("#channelranks table").data("page")
+ );
},
voteskip: function(data) {
diff --git a/www/assets/js/paginator.js b/www/assets/js/paginator.js
new file mode 100644
index 00000000..3b862ed4
--- /dev/null
+++ b/www/assets/js/paginator.js
@@ -0,0 +1,103 @@
+(function () {
+
+ var defaults = {
+ preLoadPage: function () { },
+ postLoadPage: function () { },
+ generator: function () { },
+ itemsPerPage: 20,
+ maxPages: 5
+ };
+
+ function P(items, opts) {
+ this.items = items;
+ this.opts = opts || {};
+ for(var k in defaults)
+ if(!this.opts[k])
+ this.opts[k] = defaults[k];
+ this.paginator = $("").addClass("pagination");
+ this.loadPage(0);
+ }
+
+ P.prototype.loadButtons = function (p) {
+ var pages = parseInt(this.items.length / this.opts.itemsPerPage+0.5);
+ var endcaps = pages > this.opts.maxPages;
+ this.paginator.html("");
+ if(this.items.length < this.opts.itemsPerPage)
+ return;
+ var ul = $("").appendTo(this.paginator);
+ var s = p - parseInt(this.opts.maxPages / 2);
+ s = s < 0 ? 0 : s;
+ s = s + this.opts.maxPages < pages ? s : pages - this.opts.maxPages;
+ if(endcaps) {
+ var li = $("").appendTo(ul);
+ $("").attr("href", "javascript:void(0)")
+ .html("«")
+ .click(function () {
+ this.loadPage(0);
+ }.bind(this))
+ .appendTo(li);
+
+ if(p == 0)
+ li.addClass("disabled");
+
+ if(s > 0) {
+ var sep = $("").addClass("disabled")
+ .appendTo(ul);
+ $("").attr("href", "javascript:void(0)")
+ .html("…")
+ .appendTo(sep);
+ }
+ }
+ for(var i = s; i < s + this.opts.maxPages; i++) {
+ (function (i) {
+ var li = $("").appendTo(ul);
+ if(i == p)
+ li.addClass("active");
+ $("").attr("href", "javascript:void(0)")
+ .text(i + 1)
+ .click(function () {
+ this.loadPage(i);
+ }.bind(this))
+ .appendTo(li);
+ }.bind(this))(i);
+ }
+ if(endcaps) {
+ if(s + this.opts.maxPages < pages) {
+ var sep = $("").addClass("disabled")
+ .appendTo(ul);
+ $("").attr("href", "javascript:void(0)")
+ .html("…")
+ .appendTo(sep);
+ }
+
+ var li = $("").appendTo(ul);
+ $("").attr("href", "javascript:void(0)")
+ .html("»")
+ .click(function () {
+ this.loadPage(pages - 1);
+ }.bind(this))
+ .appendTo(li);
+
+ if(p == pages - 1)
+ li.addClass("disabled");
+ }
+ }
+
+ P.prototype.loadPage = function (page) {
+ this.opts.preLoadPage(page);
+ this.loadButtons(page);
+ var s = page * this.opts.itemsPerPage;
+ var e = s + this.opts.itemsPerPage;
+ if(e > this.items.length)
+ e = this.items.length;
+ for(var i = s; i < e; i++) {
+ this.opts.generator(this.items[i], page, i);
+ }
+ this.opts.postLoadPage();
+ }
+
+ window.Paginate = function (items, opts) {
+ var p = new P(items, opts);
+ return p;
+ };
+})();
diff --git a/www/assets/js/util.js b/www/assets/js/util.js
index ec5ad9c9..19fe3ca1 100644
--- a/www/assets/js/util.js
+++ b/www/assets/js/util.js
@@ -1419,63 +1419,6 @@ function genPermissionsEditor() {
});
}
-function loadChannelRanksPage(page) {
- var entries = $("#channelranks").data("entries");
- $("#channelranks").data("page", page);
- var start = page * 20;
- var tbl = $("#channelranks table");
- if(tbl.children().length > 1) {
- $(tbl.children()[1]).remove();
- }
- for(var i = start; i < start + 20 && i < entries.length; i++) {
- var tr = $("
").appendTo(tbl);
- var name = $(" | ").text(entries[i].name).appendTo(tr);
- name.addClass(getNameColor(entries[i].rank));
- var rank = $(" | ").text(entries[i].rank)
- .css("min-width", "220px")
- .appendTo(tr);
- (function(name) {
- rank.click(function() {
- if(this.find(".rank-edit").length > 0)
- return;
- var r = this.text();
- this.text("");
- var edit = $("").attr("type", "text")
- .attr("placeholder", r)
- .addClass("rank-edit")
- .appendTo(this)
- .focus();
- if(parseInt(r) >= CLIENT.rank) {
- edit.attr("disabled", true);
- }
- function save() {
- var r = this.val();
- var r2 = r;
- if(r.trim() == "" || parseInt(r) >= CLIENT.rank || parseInt(r) < 1)
- r = this.attr("placeholder");
- r = parseInt(r) + "";
- this.parent().text(r);
- socket.emit("setChannelRank", {
- user: name,
- rank: parseInt(r)
- });
- }
- edit.blur(save.bind(edit));
- edit.keydown(function(ev) {
- if(ev.keyCode == 13)
- save.bind(edit)();
- });
- }.bind(rank));
- })(entries[i].name);
- }
- if($("#channelranks_pagination").length > 0) {
- $("#channelranks_pagination").find("li").each(function() {
- $(this).removeClass("active");
- });
- $($("#channelranks_pagination").find("li")[page]).addClass("active");
- }
-}
-
function waitUntilDefined(obj, key, fn) {
if(typeof obj[key] === "undefined") {
setTimeout(function () {
diff --git a/www/channel.html b/www/channel.html
index dc69c0f2..68d063f5 100644
--- a/www/channel.html
+++ b/www/channel.html
@@ -227,6 +227,7 @@
+