-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
126 lines (112 loc) · 2.81 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
var sort = require('sort');
var query = require('query');
var events = require('event');
var each = require('each');
var map = require('map');
var natural = require('natural-sort');
var Emitter = require('emitter');
var inherit = require('inherit');
var ap = require('ap');
module.exports = TableSorter;
/**
* TableSorter
*
* @param {Element} table
* @param {Object} options
* @api public
*/
function TableSorter(table, options) {
if (!(this instanceof TableSorter)) return new TableSorter(table, options);
var self = this;
Emitter.call(this);
options = options || {};
var defaultSort = function(h, i){
return function(a, b) {
a = a.children[i];
b = b.children[i];
return natural(a.textContent, b.textContent);
};
};
options.sort = options.sort || defaultSort;
TableSorter.defaultSort = defaultSort;
this.defaultSort = defaultSort;
this.options = options;
this.table = table;
this.order = 'none';
this.attach(table, options);
}
inherit(TableSorter, Emitter);
/**
* Get headers
*
* @param {Function} fn
* @api public
*/
TableSorter.prototype.headers = function(table){
if (this._headers) return this._headers;
var hs = this._headers = this.options.headers || query.all('tr > th', table);
return hs;
};
/**
* Get parent element for sorting
*
* @param {Element} optional table element
* @api public
*/
TableSorter.prototype.el = function(table) {
if (this._el) return this._el;
table = table || this.table;
this._el = this.options.el || query('tbody', table);
return this._el;
};
/**
* Get elements for sorting
*
* @param {Element} optional table element
* @api public
*/
TableSorter.prototype.elements = function() {
return ap(this.options.elements) || this.el().children;
};
/**
* Attach handlers to a table
*
* @param {Element} table element
* @param {Object} options
* @api public
*/
TableSorter.prototype.attach = function(table){
this.handlers(this.headers(table));
};
/**
* Set up event handlers on header elements
*
* @param {[Element]} header elements
* @param {Object} options
* @api public
*/
TableSorter.prototype.handlers = function(headers, options){
var self = this;
each(headers, function(h, i){
events.bind(h, 'click', function(e){
var srt = self.options.sort(h, i);
if (srt) self.sort(srt, this.order, h, i);
});
});
};
/**
* Sort rows
*
* @param {Function} element sorting function
* @param {String} order {asc,desc}
* @param {Element} optional related header element for sort event
* @param {Number} optional related header index for sort event
* @api public
*/
TableSorter.prototype.sort = function(fn, order, h, i) {
var el = this.el();
var els = this.elements();
this.order = order = order || this.order === 'asc'? 'desc' : 'asc';
sort[order](el, els, fn);
this.emit('sort', order, h, i, fn);
};