Skip to content

Instantly share code, notes, and snippets.

@huyderman
Created December 9, 2011 08:32
Show Gist options
  • Save huyderman/1450746 to your computer and use it in GitHub Desktop.
Save huyderman/1450746 to your computer and use it in GitHub Desktop.
Paginator
/**
* Simple example use of Paginator and jQuery
* @requires jQuery
* @requires Paginator.js
*/
var pager = new Paginator();
pager.setCurrent(5);
pager.setLast(23);
var list = $("<ul class='pagelist'/>");
var addPage = function(i, val){ $("<li><a href='foo/"+val+"' />"+val+"</a></li>").appendTo(list) });
$.each(pager.getHead(), addPage);
list.append("<li>...</li>");
$.each(pager.getBody(), addPage);
list.append("<li>...</li>");
$.each(pager.getTail(), addPage);
list.appendTo("body");
###*
* @fileOverview Script for generating Flickr style pagination.
* @author Jo-Herman Haugholt <jo-herman.haugholt@sectoralarm.com>
###
###*
* @class Pagination object. Instances of this class can return the head, body and tail subsets of pages.
###
class Paginator
###*
* @public
* @property {number} first The first page
* @default 1
###
"first": null
###*
* @public
* @property {number} last The last page. Required.
###
"last": null
###*
* @private
* @property {number} next The next page.
###
"next": undefined
###*
* @private
* @property {number} prev The previous page
###
"prev": undefined
###*
* @private
* @property {number} current The current page
###
"current": undefined
###*
* @public
* @property {number} peek How many pages to "peek" before and after the
* previous and next page respectivly.
* @default 2
###
"peek": 2
###* @constructor ###
constructor: (@first=1, @last, @next, @prev, @current)->
###*
* @public
* @function
* @returns {number} The current page. If <code>undefined</code>, it is extrapolated from
* {@link next} and/or {@link prev}. If it can't be extrapolated, it
* returns <code>undefined</code>.
###
"getCurrent": ->
return @current if @current?
return (@next+@prev)/2 if @next? and @prev?
return @next-1 if @next?
return @prev+1 if @prev?
return undefined
"setCurrent": (@current) ->
###*
* @public
* @function
* @returns {number} The next page. If <code>undefined</code>, and {@link current} is defined
* it will try to extrapolate the next page. Otherwise it returns
* <code>undefined</code>.
###
"getNext": ->
return @next if @next?
return undefined if not @current?
return @current - (@prev - @current) if @prev?
return @current+1
"setNext": (@next) ->
###*
* @public
* @function
* @returns {number} The previous page. If <code>undefined</code>, and {@link current} is
* defined it will try to extrapolate the previous page. Otherwise it
* returns <code>undefined</code>.
###
"getPrev": ->
return @prev if @prev?
return undefined if not @current?
return @current - (@next - @current) if @next?
return @current-1
"setPrev": (@prev) ->
"getLast": -> @last
"setLast": (@last) ->
###*
* @public
* @function
* @returns {Array.<number>} An array containing the "head" pages. If
* {@link first} would be included in the "body"
* pages, this function will return an empty array.
###
"getHead": ->
current = @getCurrent()
i = @peek+1
j = 2*i
k = 3*i-1
if not current? or current < @first+k then return []
else
end = @first+@peek-1
end = @last if end > @last
[@first..end]
###*
* @public
* @function
* @returns {Array.<number>} An array containing the "body" of pages.
###
"getBody": ->
current = @getCurrent()
if not current? then return [@first..@last]
i = @peek+1
j = 2*i
k = 3*i-1
prev = @getPrev()
start = if prev? then prev-@peek else @first
start = @first if start < @first
start = @last - j if current >= @last-i
start = @first if current < @first+k
next = @getNext()
end = if next? then next+@peek else @last
end = @last if end > @last
end = @first + j if current <= @first+i
end = @last if current > @last-k
[start..end]
###*
* @public
* @function
* @returns {Array.<number>} An array containing the "tail" pages. If
* {@link last} would be included in the "body"
* pages, this function will return an empty array.
###
"getTail": ->
current = @getCurrent()
i = @peek+1
j = 2*i
k = 3*i-1
if not current? or current > @last-k then return []
else
start = @last-@peek+1
start = @first if start < @first
return [start..@last]
window["Paginator"] = Paginator
(function() {
/**
* @fileOverview Script for generating Flickr style pagination.
* @author Jo-Herman Haugholt <jo-herman.haugholt@sectoralarm.com>
*/
/**
* @class Pagination object. Instances of this class can return the head, body and tail subsets of pages.
*/ var Paginator;
Paginator = (function() {
/**
* @public
* @property {number} first The first page
* @default 1
*/ Paginator.prototype["first"] = null;
/**
* @public
* @property {number} last The last page. Required.
*/
Paginator.prototype["last"] = null;
/**
* @private
* @property {number} next The next page.
*/
Paginator.prototype["next"] = void 0;
/**
* @private
* @property {number} prev The previous page
*/
Paginator.prototype["prev"] = void 0;
/**
* @private
* @property {number} current The current page
*/
Paginator.prototype["current"] = void 0;
/**
* @public
* @property {number} peek How many pages to "peek" before and after the
* previous and next page respectivly.
* @default 2
*/
Paginator.prototype["peek"] = 2;
/** @constructor */
function Paginator(first, last, next, prev, current) {
this.first = first != null ? first : 1;
this.last = last;
this.next = next;
this.prev = prev;
this.current = current;
}
/**
* @public
* @function
* @returns {number} The current page. If <code>undefined</code>, it is extrapolated from
* {@link next} and/or {@link prev}. If it can't be extrapolated, it
* returns <code>undefined</code>.
*/
Paginator.prototype["getCurrent"] = function() {
if (this.current != null) {
return this.current;
}
if ((this.next != null) && (this.prev != null)) {
return (this.next + this.prev) / 2;
}
if (this.next != null) {
return this.next - 1;
}
if (this.prev != null) {
return this.prev + 1;
}
};
Paginator.prototype["setCurrent"] = function(current) {
this.current = current;
};
/**
* @public
* @function
* @returns {number} The next page. If <code>undefined</code>, and {@link current} is defined
* it will try to extrapolate the next page. Otherwise it returns
* <code>undefined</code>.
*/
Paginator.prototype["getNext"] = function() {
if (this.next != null) {
return this.next;
}
if (!(this.current != null)) {
return;
}
if (this.prev != null) {
return this.current - (this.prev - this.current);
}
return this.current + 1;
};
Paginator.prototype["setNext"] = function(next) {
this.next = next;
};
/**
* @public
* @function
* @returns {number} The previous page. If <code>undefined</code>, and {@link current} is
* defined it will try to extrapolate the previous page. Otherwise it
* returns <code>undefined</code>.
*/
Paginator.prototype["getPrev"] = function() {
if (this.prev != null) {
return this.prev;
}
if (!(this.current != null)) {
return;
}
if (this.next != null) {
return this.current - (this.next - this.current);
}
return this.current - 1;
};
Paginator.prototype["setPrev"] = function(prev) {
this.prev = prev;
};
Paginator.prototype["getLast"] = function() {
return this.last;
};
Paginator.prototype["setLast"] = function(last) {
this.last = last;
};
/**
* @public
* @function
* @returns {Array.<number>} An array containing the "head" pages. If
* {@link first} would be included in the "body"
* pages, this function will return an empty array.
*/
Paginator.prototype["getHead"] = function() {
var current, end, i, j, k, _i, _ref, _results;
current = this.getCurrent();
i = this.peek + 1;
j = 2 * i;
k = 3 * i - 1;
if (!(current != null) || current < this.first + k) {
return [];
} else {
end = this.first + this.peek - 1;
if (end > this.last) {
end = this.last;
}
return (function() {
_results = [];
for (var _i = _ref = this.first; _ref <= end ? _i <= end : _i >= end; _ref <= end ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this, arguments);
}
};
/**
* @public
* @function
* @returns {Array.<number>} An array containing the "body" of pages.
*/
Paginator.prototype["getBody"] = function() {
var current, end, i, j, k, next, prev, start, _i, _j, _ref, _ref2, _results, _results2;
current = this.getCurrent();
if (!(current != null)) {
return (function() {
_results = [];
for (var _i = _ref = this.first, _ref2 = this.last; _ref <= _ref2 ? _i <= _ref2 : _i >= _ref2; _ref <= _ref2 ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this, arguments);
}
i = this.peek + 1;
j = 2 * i;
k = 3 * i - 1;
prev = this.getPrev();
start = prev != null ? prev - this.peek : this.first;
if (start < this.first) {
start = this.first;
}
if (current >= this.last - i) {
start = this.last - j;
}
if (current < this.first + k) {
start = this.first;
}
next = this.getNext();
end = next != null ? next + this.peek : this.last;
if (end > this.last) {
end = this.last;
}
if (current <= this.first + i) {
end = this.first + j;
}
if (current > this.last - k) {
end = this.last;
}
return (function() {
_results2 = [];
for (var _j = start; start <= end ? _j <= end : _j >= end; start <= end ? _j++ : _j--){ _results2.push(_j); }
return _results2;
}).apply(this, arguments);
};
/**
* @public
* @function
* @returns {Array.<number>} An array containing the "tail" pages. If
* {@link last} would be included in the "body"
* pages, this function will return an empty array.
*/
Paginator.prototype["getTail"] = function() {
var current, i, j, k, start, _i, _ref, _results;
current = this.getCurrent();
i = this.peek + 1;
j = 2 * i;
k = 3 * i - 1;
if (!(current != null) || current > this.last - k) {
return [];
} else {
start = this.last - this.peek + 1;
if (start < this.first) {
start = this.first;
}
return (function() {
_results = [];
for (var _i = start, _ref = this.last; start <= _ref ? _i <= _ref : _i >= _ref; start <= _ref ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this, arguments);
}
};
return Paginator;
})();
window["Paginator"] = Paginator;
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment