@danielgindi/dgtable.js 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,183 @@
1
+ 'use strict';
2
+
3
+ // Define class RowCollection
4
+ function RowCollection () {
5
+
6
+ // Instantiate an Array. Seems like the `.length = ` of an inherited Array does not work well.
7
+ // I will not use the IFRAME solution either in fear of memory leaks, and we're supporting large datasets...
8
+ let collection = [];
9
+
10
+ // Synthetically set the 'prototype'
11
+ Object.assign(collection, RowCollection.prototype);
12
+
13
+ // Call initializer
14
+ collection.initialize.apply(collection, arguments);
15
+
16
+ return collection;
17
+ }
18
+
19
+ // Inherit Array
20
+ RowCollection.prototype = [];
21
+
22
+ RowCollection.prototype.initialize = function (options) {
23
+
24
+ options = options || {};
25
+
26
+ /** @field {string} sortColumn */
27
+ this.sortColumn = options.sortColumn == null ? [] : options.sortColumn;
28
+ };
29
+
30
+ /**
31
+ * @param {Object|Object[]} rows - row or array of rows to add to this collection
32
+ * @param {number?} at - position to insert rows at
33
+ */
34
+ RowCollection.prototype.add = function (rows, at) {
35
+ let isArray = ('splice' in rows && 'length' in rows), i, len;
36
+ if (isArray) {
37
+ if (typeof at === 'number') {
38
+ for (i = 0, len = rows.length; i < len; i++) {
39
+ this.splice(at++, 0, rows[i]);
40
+ }
41
+ } else {
42
+ for (i = 0, len = rows.length; i < len; i++) {
43
+ this.push(rows[i]);
44
+ }
45
+ }
46
+ } else {
47
+ if (typeof at === 'number') {
48
+ this.splice(at, 0, rows);
49
+ } else {
50
+ this.push(rows);
51
+ }
52
+ }
53
+ };
54
+
55
+ /**
56
+ * @param {Object|Object[]=} rows Row or array of rows to add to this collection
57
+ */
58
+ RowCollection.prototype.reset = function (rows) {
59
+ this.length = 0;
60
+ if (rows) {
61
+ this.add(rows);
62
+ }
63
+ };
64
+
65
+ /**
66
+ * @param {Function} filterFunc - Filtering function
67
+ * @param {Object|null?} args - Options to pass to the function
68
+ * @returns {RowCollection} success result
69
+ */
70
+ RowCollection.prototype.filteredCollection = function (filterFunc, args) {
71
+ if (filterFunc && args) {
72
+ let rows = new RowCollection({
73
+ sortColumn: this.sortColumn,
74
+ onComparatorRequired: this.onComparatorRequired,
75
+ customSortingProvider: this.customSortingProvider,
76
+ });
77
+
78
+ for (let i = 0, len = this.length, row; i < len; i++) {
79
+ row = this[i];
80
+ if (filterFunc(row, args)) {
81
+ row['__i'] = i;
82
+ rows.push(row);
83
+ }
84
+ }
85
+ return rows;
86
+ } else {
87
+ return null;
88
+ }
89
+ };
90
+
91
+ /**
92
+ * @type {function(columnName: string, descending: boolean, defaultComparator: function(a,b):number)|null|undefined}
93
+ */
94
+ RowCollection.prototype.onComparatorRequired = null;
95
+ /**
96
+ * @type {function(data: any[], sort: function(any[]):any[]):any[]|null|undefined}
97
+ */
98
+ RowCollection.prototype.customSortingProvider = null;
99
+
100
+ let nativeSort = RowCollection.prototype.sort;
101
+
102
+ function getDefaultComparator(column, descending) {
103
+ let columnName = column.column;
104
+ let comparePath = column.comparePath || columnName;
105
+ if (typeof comparePath === 'string') {
106
+ comparePath = comparePath.split('.');
107
+ }
108
+ let pathLength = comparePath.length,
109
+ hasPath = pathLength > 1,
110
+ i;
111
+
112
+ let lessVal = descending ? 1 : -1, moreVal = descending ? -1 : 1;
113
+ return function(leftRow, rightRow) {
114
+ let leftVal = leftRow[comparePath[0]],
115
+ rightVal = rightRow[comparePath[0]];
116
+ if (hasPath) {
117
+ for (i = 1; i < pathLength; i++) {
118
+ leftVal = leftVal && leftVal[comparePath[i]];
119
+ rightVal = rightVal && rightVal[comparePath[i]];
120
+ }
121
+ }
122
+ if (leftVal === rightVal) return 0;
123
+ if (leftVal == null) return lessVal;
124
+ if (rightVal == null) return moreVal;
125
+ if (leftVal < rightVal) return lessVal;
126
+ return moreVal;
127
+ };
128
+ }
129
+
130
+ /**
131
+ * @returns {Function|undefined} the comparator that was used
132
+ */
133
+ RowCollection.prototype.sort = function () {
134
+ let comparator;
135
+
136
+ if (this.sortColumn.length) {
137
+ let comparators = [];
138
+
139
+ for (let i = 0; i < this.sortColumn.length; i++) {
140
+ comparator = null;
141
+ const defaultComparator = getDefaultComparator(this.sortColumn[i], this.sortColumn[i].descending);
142
+ if (this.onComparatorRequired) {
143
+ comparator = this.onComparatorRequired(this.sortColumn[i].column, this.sortColumn[i].descending, defaultComparator);
144
+ }
145
+ if (!comparator) {
146
+ comparator = defaultComparator;
147
+ }
148
+ comparators.push(comparator.bind(this));
149
+ }
150
+
151
+ if (comparators.length === 1) {
152
+ comparator = comparators[0];
153
+ } else {
154
+ let len = comparators.length,
155
+ value;
156
+
157
+ comparator = function(leftRow, rightRow) {
158
+ for (let i = 0; i < len; i++) {
159
+ value = comparators[i](leftRow, rightRow);
160
+ if (value !== 0) {
161
+ return value;
162
+ }
163
+ }
164
+ return value;
165
+ };
166
+ }
167
+
168
+ const sorter = data => nativeSort.call(data, comparator);
169
+
170
+ if (this.customSortingProvider) {
171
+ let results = this.customSortingProvider(this, sorter);
172
+ if (results !== this) {
173
+ this.splice(0, this.length, ...results);
174
+ }
175
+ } else {
176
+ sorter(this);
177
+ }
178
+ }
179
+
180
+ return comparator;
181
+ };
182
+
183
+ export default RowCollection;
package/src/util.js ADDED
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ export const find = function find (array, predicate) {
4
+ for (let i = 0, len = array.length; i >= 0 && i < len; i += 1) {
5
+ if (predicate(array[i], i, array))
6
+ return array[i];
7
+ }
8
+ };
9
+
10
+ export const htmlEncode = function htmlEncode (text) {
11
+ return text.replace(/&/g, "&amp;")
12
+ .replace(/</g, "&lt;")
13
+ .replace(/>/g, "&gt;")
14
+ .replace(/'/g, "&#39;")
15
+ .replace(/"/g, "&quot;")
16
+ .replace(/\n/g, '<br />');
17
+ };