-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReactTableSorter.jsx
More file actions
122 lines (108 loc) · 3.67 KB
/
ReactTableSorter.jsx
File metadata and controls
122 lines (108 loc) · 3.67 KB
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
/**
* @jsx React.DOM
*/
var TableSorter = React.createClass({
getInitialState: function() {
if(!this.props.items)
throw ('props.items required');
return {
sortColumn: this.props.sortColumn || null,
sortASC: this.props.sortASC || true,
pageSize: this.props.pageSize || 25,
pageSizeOptions: this.props.pageSizeOptions || [{label: 'ten', value: 10}, {label: '25', value: 25}, {label: '50', value: 50}, {label: '100', value: 100}],
pageSizeOptionLabelPath: this.props.pageSizeOptionLabelPath || 'label',
pageSizeOptionValuePath: this.props.pageSizeOptionValuePath || 'value',
currentPage: this.props.currentPage || 0,
hiddenColumns: this.props.hiddenColumns || []
};
},
changePageSize: function(e) {
var ps = parseInt(e.currentTarget.value);
this.setState({
pageSize: ps,
currentPage: 0 // Go back to the first page on page change
});
},
changeSort: function(e) {
var currentSort = this.state.sortColumn,
newSort = e.currentTarget.getAttribute('data-sort-column'),
obj = {sortColumn : newSort};
if(currentSort === newSort)
obj.sortASC = !this.state.sortASC
this.setState(obj);
},
changePage: function(e){
var pageIndex = e.currentTarget.getAttribute('data-page-index');
this.setState({
currentPage: pageIndex
});
},
toggleColumnVisibility: function () {
throw('Implement');
},
sort: function(a, b){
var sortColumn = this.state.sortColumn,
sortOrder = this.state.sortASC ? 1 : -1;
return sortOrder * ((a[sortColumn] < b[sortColumn]) ? -1 : (a[sortColumn] > b[sortColumn]) ? 1 : 0);
},
render: function() {
var self = this,
firstItem = this.props.items[0],
columns = this.props.columns || Object.getOwnPropertyNames(firstItem).map(function(prop){ return {name: prop}}),
startIndex = (this.state.currentPage * this.state.pageSize),
endIndex = startIndex + this.state.pageSize,
rows = this.props.items,
numPages = Math.ceil(rows.length / this.state.pageSize),
numOptions = [];
var headers = columns.map(function(column){
return (<th style={{padding:0}}><a onClick={self.changeSort} data-sort-column={column.name} style={{padding:'8px', display:'block', width: '100%'}}>{column.displayName || column.name}</a></th>);
});
if(this.state.sortColumn)
rows = rows.sort(this.sort);
rows = rows.filter(function(item, index){
return index >= startIndex && index < endIndex
})
.map(function(item){
return (
<tr key={item._id}>
{
columns.map(function(col) {
return col.template && typeof(col.template) === 'function' ? <td>{col.template(item)}</td> : (<td>{item[col.name]}</td>);
})
}
</tr>
)
});
for(var i = 0; i < numPages; i++){
numOptions.push(<li className={this.state.currentPage == i ? 'active' : ''}><a onClick={this.changePage} data-page-index={i}>{i + 1}</a></li>);
}
return (
<table className={this.props.tableClassName}>
<thead className={this.props.tHeadClassName}>
<tr>
{headers}
</tr>
</thead>
<tbody className={this.props.tBodyClassName}>
{rows}
</tbody>
<tfoot className={this.props.tFootClassName}>
<tr>
<td colSpan={headers.length} style={{textAlign: 'center'}}>
<ul className='pagination' style={{marginTop:0}}>
{numOptions}
</ul>
<label className="pull-right">
<select className="form-control" onChange={this.changePageSize} value={this.state.pageSize}>
{this.state.pageSizeOptions.map(function (item) {
return (<option value={item[this.state.pageSizeOptionValuePath]}>{item[this.state.pageSizeOptionLabelPath]}</option>)
}.bind(this))}
</select>
</label>
</td>
</tr>
</tfoot>
</table>
);
}
});