8000 Seperated PaginationButton.js from Pagination.js · react-bootstrap/react-bootstrap@f4bf7a7 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit f4bf7a7

Browse files
committed
Seperated PaginationButton.js from Pagination.js
1 parent 13d8610 commit f4bf7a7

File tree

5 files changed

+148
-73
lines changed

5 files changed

+148
-73
lines changed

docs/examples/PaginationAdvance.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ const PaginationAdvance = React.createClass({
55
};
66
},
77

8+
handleSelect(event, selectedEvent){
9+
this.setState({
10+
activePage: selectedEvent.eventKey
11+
});
12+
},
13+
814
render() {
915
return (
1016
<Pagination
@@ -16,7 +22,7 @@ const PaginationAdvance = React.createClass({
1622
items={20}
1723
maxButtons={5}
1824
activePage={this.state.activePage}
19-
onSelect={activePage => this.setState({activePage})} />
25+
onSelect={this.handleSelect} />
2026
);
2127
}
2228
});

docs/examples/PaginationBasic.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,34 @@ const PaginationBasic = React.createClass({
55
};
66
},
77

8+
handleSelect(event, selectedEvent){
9+
this.setState({
10+
activePage: selectedEvent.eventKey
11+
});
12+
},
13+
814
render() {
915
return (
1016
<div>
1117
<Pagination
1218
bsSize='large'
1319
items={10}
1420
activePage={this.state.activePage}
15-
onSelect={activePage => this.setState({activePage})} />
21+
onSelect={this.handleSelect} />
1622
<br />
1723

1824
<Pagination
1925
bsSize='medium'
2026
items={10}
2127
activePage={this.state.activePage}
22-
onSelect={activePage => this.setState({activePage})} />
28+
onSelect={this.handleSelect} />
2329
<br />
2430

2531
<Pagination
2632
bsSize='small'
2733
items={10}
2834
activePage={this.state.activePage}
29-
onSelect={activePage => this.setState({activePage})} />
35+
onSelect={this.handleSelect} />
3036
</div>
3137
);
3238
}

src/Pagination.js

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import classNames from 'classnames';
3-
43
import BootstrapMixin from './BootstrapMixin';
4+
import PaginationButton from './PaginationButton';
55

66
const Pagination = React.createClass({
77
mixins: [BootstrapMixin],
@@ -32,24 +32,12 @@ const Pagination = React.createClass({
3232
};
3333
},
3434

35-
handleSelect(pagenumber) {
35+
handleSelect(event, selectedEvent) {
3636
if(this.props.onSelect){
37-
this.props.onSelect(pagenumber);
37+
this.props.onSelect(event, selectedEvent);
3838
}
3939
},
4040

41-
renderButton({child, key, className, onClick}){
42-
//TODO: replace <a> with <SafeAnchor> when it is avaliable
43-
return (
44-
<li
45-
key={key}
46-
onClick={onClick}
47-
className={className}>
48-
<a href='#' onClick={e => e.preventDefault()}>{child}</a>
49-
</li>
50-
);
51-
},
52-
5341
renderPageButtons() {
5442
let pageButtons = [];
5543
let startPage, endPage, hasHiddenPagesBefore, hasHiddenPagesAfter;
@@ -73,66 +61,91 @@ const Pagination = React.createClass({
7361

7462
for(let pagenumber = startPage; pagenumber <= endPage; pagenumber++){
7563
pageButtons.push(
76-
this.renderButton({
77-
child: pagenumber,
78-
key: pagenumber,
79-
className: pagenumber === this.props.activePage ? 'active' : null,
80-
onClick: this.handleSelect.bind(this, pagenumber)
81-
})
64+
<PaginationButton
65+
key={pagenumber}
66+
eventKey={pagenumber}
67+
className={pagenumber === this.props.activePage ? 'active' : null}
68+
onSelect={this.handleSelect}>
69+
{pagenumber}
70+
</PaginationButton>
8271
);
8372
}
8473

8574
if(this.props.maxButtons && hasHiddenPagesAfter && this.props.ellipsis){
8675
pageButtons.push(
87-
this.renderButton({
88-
child: (<span aria-label='More'>...</span>),
89-
key: 'ellipsis',
90-
className: 'disabled'
91-
})
76+
<PaginationButton
77+
key='ellipsis'
78+
className='disabled'>
79+
<span aria-label='More'>...</span>
80+
</PaginationButton>
9281
);
9382
}
9483

9584
return pageButtons;
9685
},
9786

9887
renderPrev() {
99-
return this.props.prev ?
100-
this.renderButton({
101-
child: (<span aria-label='Previous'>&lsaquo;</span>),
102-
key: 'prev',
103-
className: this.props.activePage === 1 ? 'disabled' : null,
104-
onClick: this.handleSelect.bind(this, this.props.activePage - 1)
105-
}) : null;
88+
if(!this.props.prev){
89+
return null;
90+
}
91+
92+
return (
93+
<PaginationButton
94+
key='prev'
95+
eventKey={this.props.activePage - 1}
96+
className={this.props.activePage === 1 ? 'disabled' : null}
97+
onSelect={this.handleSelect}>
98+
<span aria-label='Previous'>&lsaquo;</span>
99+
</PaginationButton>
100+
);
106101
},
107102

108103
renderNext() {
109-
return this.props.next ?
110-
this.renderButton({
111-
child: (<span aria-label='Next'>&rsaquo;</span>),
112-
key: 'next',
113-
className: this.props.activePage === this.props.items ? 'disabled' : null,
114-
onClick: this.handleSelect.bind(this, this.props.activePage + 1)
115-
}) : null;
104+
if(!this.props.next){
105+
return null;
106+
}
107+
108+
return (
109+
<PaginationButton
110+
key='next'
111+
eventKey={this.props.activePage + 1}
112+
className={this.props.activePage === this.props.items ? 'disabled' : null}
113+
onSelect={this.handleSelect}>
114+
<span aria-label='Next'>&rsaquo;</span>
115+
</PaginationButton>
116+
);
116117
},
117118

118119
renderFirst() {
119-
return this.props.first ?
120-
this.renderButton({
121-
child: (<span aria-label='First'>&laquo;</span>),
122-
key: 'first',
123-
className: this.props.activePage === 1 ? 'disabled' : null,
124-
onClick: this.handleSelect.bind(this, 1)
125-
}) : null;
120+
if(!this.props.first){
121+
return null;
122+
}
123+
124+
return (
125+
<PaginationButton
126+
key='first'
127+
eventKey={1}
128+
className={this.props.activePage === 1 ? 'disabled' : null}
129+
onSelect={this.handleSelect}>
130+
<span aria-label='First'>&laquo;</span>
131+
</PaginationButton>
132+
);
126133
},
127134

128135
renderLast() {
129-
return this.props.last ?
130-
this.renderButton({
131-
child: (<span aria-label='Last'>&raquo;</span>),
132-
key: 'last',
133-
className: this.props.activePage === this.props.items ? 'disabled' : null,
134-
onClick: this.handleSelect.bind(this, this.props.items)
135-
}) : null;
136+
if(!this.props.last){
137+
return null;
138+
}
139+
140+
return (
141+
<PaginationButton
142+
key='last'
143+
eventKey={this.props.items}
144+
className={this.props.activePage === this.props.items ? 'disabled' : null}
145+
onSelect={this.handleSelect}>
146+
<span aria-label='Last'>&raquo;</span>
147+
</PaginationButton>
148+
);
136149
},
137150

138151
render() {

src/PaginationButton.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import createSelectedEvent from './utils/createSelectedEvent';
3+
4+
class PaginationButton extends React.Component {
5+
constructor(props) {
6+
super(props);
7+
8+
this.handleClick = this.handleClick.bind(this);
9+
}
10+
11+
handleClick(event) {
12+
// This would go away once SafeAnchor is available
13+
event.preventDefault();
14+
15+
if (this.props.onSelect) {
16+
let selectedEvent = createSelectedEvent(this.props.eventKey);
17+
this.props.onSelect(event, selectedEvent);
18+
}
19+
}
20+
21+
render() {
22+
return (
23+
<li className={this.props.className}>
24+
<a href='#' onClick={this.handleClick}>{this.props.children}</a>
25+
</li>
26+
);
27+
}
28+
}
29+
30+
PaginationButton.PropTypes = {
31+
className: React.PropTypes.string,
32+
eventKey: React.PropTypes.oneOfType([
33+
React.PropTypes.string,
34+
React.PropTypes.number
35+
]),
36+
onSelect: React.PropTypes.func
37+
};
38+
39+
export default PaginationButton;

test/PaginationSpec.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ describe('Pagination', function () {
1818
);
1919
let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li');
2020
assert.equal(pageButtons.length, 5);
21-
assert.equal(pageButtons[2].getDOMNode().getAttribute('class').match(/active/)[0], 'active');
21+
React.findDOMNode(pageButtons[2]).className.should.match(/\bactive\b/);
2222
});
2323

2424
it('Should call onSelect when page button is selected', function (done) {
25-
function onSelect(pagenumber) {
26-
assert.equal(pagenumber, 2);
25+
function onSelect(event, selectedEvent) {
26+
assert.equal(selectedEvent.eventKey, 2);
2727
done();
2828
}
2929

@@ -36,32 +36,43 @@ describe('Pagination', function () {
3636
);
3737
});
3838

39-
it('Should only show part of buttons when given maxButtons', function () {
39+
it('Should only show part of buttons and active button in the middle of buttons when given maxButtons', function () {
4040
let instance = ReactTestUtils.renderIntoDocument(
4141
<Pagination
42-
items={20}
43-
activePage={8}
44-
maxButtons={5} />
42+
items={30}
43+
activePage={10}
44+
maxButtons={9} />
4545
);
4646
let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li');
47-
// include ellipsis button
48-
assert.equal(pageButtons.length, 6);
47+
// 9 visible page buttons and 1 ellipsis button
48+
assert.equal(pageButtons.length, 10);
4949

5050
// active button is the second one
51-
assert.equal(pageButtons[0].getDOMNode().firstChild.innerText, '7');
52-
assert.equal(pageButtons[1].getDOMNode().getAttribute('class').match(/active/)[0], 'active');
51+
assert.equal(React.findDOMNode(pageButtons[0]).firstChild.innerText, '6');
52+
React.findDOMNode(pageButtons[4]).className.should.match(/\bactive\b/);
5353
});
5454

55-
it('Should show the first and last button', function () {
55+
it('Should show the first, last, prev and next button', function () {
56+
5657
let instance = ReactTestUtils.renderIntoDocument(
5758
<Pagination
5859
first={true}
5960
last={true}
60-
items={5} />
61+
prev={true}
62+
next={true}
63+
maxButtons={3}
64+
activePage={10}
65+
items={20} />
6166
);
6267
let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li');
63-
// add 2 more button
64-
assert.equal(pageButtons.length, 7);
68+
// add first, last, prev, next and ellipsis button
69+
assert.equal(pageButtons.length, 8);
70+
71+
assert.equal(React.findDOMNode(pageButtons[0]).innerText, '«');
72+
assert.equal(React.findDOMNode(pageButtons[1]).innerText, '‹');
73+
assert.equal(React.findDOMNode(pageButtons[6]).innerText, '›');
74+
assert.equal(React.findDOMNode(pageButtons[7]).innerText, '»');
75+
6576
});
6677

6778

0 commit comments

Comments
 (0)
0