-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathjquery.table.js
More file actions
126 lines (107 loc) · 4.02 KB
/
jquery.table.js
File metadata and controls
126 lines (107 loc) · 4.02 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
123
124
125
// Copyright 2011, Klaus Ganser <http://kganser.com>
// MIT Licensed, with this copyright and permission notice
// <http://opensource.org/licenses/MIT>
(function($) {
var Node = function(element, value, parent, insert, remove) {
this.element = element;
this.value = value;
this.parent = parent;
this.insertFn = insert || function() {};
this.removeFn = remove || function() {};
this.children = [];
};
Node.prototype = {
get: function(index) {
return this.children[index];
},
insert: function(value, index) {
if (typeof index != 'number') index = this.children.length;
this.children.splice(index, 0, this.insertFn(this, value, index));
return this;
},
insertAll: function(values, index) {
if (typeof index != 'number') index = this.children.length;
values.forEach(function(value, i) { this.insert(value, index+i); }.bind(this));
return this;
},
remove: function(index) {
var removed = this.children.splice(index, 1);
if (removed[0]) this.removeFn(removed[0], index);
return this;
},
sort: function(compare) {
var sorted = this.children.slice().sort(compare);
this.children.forEach(function(child, index) {
if (child != sorted[index])
this.remove(index).insert(sorted[index].value, index);
}.bind(this));
return this;
}
};
var format = {
table: function(columns, hooks) {
var table = document.createElement('table'),
row = hooks.row(columns, -1);
table.appendChild(document.createElement('thead')).appendChild(row[0]);
columns.forEach(function(value, index) { row[1].appendChild(hooks.cell(value, value, index, null)); });
return [table, table.appendChild(document.createElement('tbody'))];
},
row: function(value, index) {
var row = document.createElement('tr');
return [row, row];
},
cell: function(key, value, index, row) {
return document.createElement(row ? 'td' : 'th').appendChild(document.createTextNode(value)).parentNode;
}
};
$.fn.table = function(data, columns, hooks) {
if (!columns) {
columns = {};
data.forEach(function(row) {
Object.keys(row).forEach(function(column) { columns[column] = 1; });
});
columns = Object.keys(columns);
}
if (!hooks) hooks = format;
else for (var type in format)
if (typeof hooks[type] != 'function')
hooks[type] = format[type];
var table = hooks.table(columns, hooks);
this.append(table[0]);
var node = new Node(table[1], [], null, function(parent, value, index) {
var table = parent.element,
row = hooks.row(value, index);
if (index) table.contents().eq(index-1).after(row[0]);
else table.prepend(row[0]);
parent.value.splice(index, 0, value);
return new Node(row[1], value, parent, function(parent, value, index) {
var row = parent.element,
cell = hooks.cell(columns[index], value, index, parent.value);
if (index) row.contents().eq(index-1).after(cell);
else row.prepend(cell);
return parent.value[columns[index]] = value;
}, function(previous, index) {
previous.element.remove();
delete previous.parent.value[columns[index]];
}).insertAll(columns.map(function(column) { return value[column]; }));
}, function(previous, index) {
previous.element.remove();
previous.parent.value.splice(index, 1);
}).insertAll(data);
return {
get: function(row, column) {
if (row == undefined) return node.value;
if (column == undefined) return node.get(row).value;
return node.get(row).get(column);
},
insert: node.insert.bind(node),
insertAll: node.insertAll.bind(node),
remove: node.remove.bind(node),
sort: function(comparator) {
return node.sort(function(a, b) {
return comparator(a.value, b.value);
});
}
};
};
})(jQuery);