-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
129 lines (109 loc) · 3.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/** @jsx React.DOM */
'use strict';
var React = require('react');
// Slighlty modified from underscore source
function range(start, stop) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
var length = Math.max(stop - start, 0);
var idx = 0;
var arr = new Array(length);
while(idx < length) {
arr[idx++] = start;
start += 1;
}
return arr;
}
/**
* React Paginator
*
* @prop {number} numPages - Available number of pages
* @prop {number} [maxPages] - Max number of pages to display
* @prop {function} [onClick] - Fired on every click and passes the page number
*/
module.exports = React.createClass({
propTypes: {
numPages: React.PropTypes.number.isRequired,
maxPages: React.PropTypes.number,
onClick: React.PropTypes.func
},
getDefaultProps: function() {
return {
maxPages: 3
};
},
getInitialState: function() {
return {
page: 1
};
},
/**
* Triggered by any button click within the paginator.
*
* @param {number} n - Page number
*/
onClick: function(n) {
// n is out of range, don't do anything
if (n > this.props.numPages || n < 1) return;
if (this.props.onClick) this.props.onClick(n);
this.setState({ page: n });
},
/**
* Returns the number of page numbers
*/
getDisplayCount: function() {
if (this.props.numPages > this.props.maxPages) {
return this.props.maxPages;
}
return this.props.numPages;
},
/**
* Returns a range [start, end]
*/
getPageRange: function() {
var displayCount = this.getDisplayCount();
var page = this.state.page;
// Check position of cursor, zero based
var idx = (page - 1) % displayCount;
// list should not move if cursor isn't passed this part of the range
var start = page - idx;
// remaining pages
var remaining = this.props.numPages - page;
// Don't move cursor right if the range will exceed the number of pages
// in other words, we've reached the home stretch
if (page > displayCount && remaining < displayCount) {
// add 1 due to the implementation of `range`
start = this.props.numPages - displayCount + 1;
}
return range(start, start + displayCount);
},
preventDefault: function(e) {
e.preventDefault();
},
render: function() {
var page = this.state.page;
var prevClassName = page === 1 ? 'disabled' : '';
var nextClassName = page >= this.props.numPages ? 'disabled' : '';
return (
<ul className='pagination'>
<li className={prevClassName} onClick={this.onClick.bind(this, page - 1)}>
<a href='#' onClick={this.preventDefault}><i className='glyphicon glyphicon-chevron-left' /></a>
</li>
{this.getPageRange().map(this.renderPage, this)}
<li className={nextClassName} onClick={this.onClick.bind(this, page + 1)}>
<a href='#' onClick={this.preventDefault}><i className='glyphicon glyphicon-chevron-right' /></a>
</li>
</ul>
);
},
renderPage: function(n, i) {
var cls = this.state.page === n ? 'active' : '';
return (
<li key={i} className={cls} onClick={this.onClick.bind(this, n)}>
<a href='#' onClick={this.preventDefault}>{n}</a>
</li>
);
}
});