adore-datatable 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.
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/package.json +78 -0
- package/src/body-renderer.js +163 -0
- package/src/cellmanager.js +934 -0
- package/src/columnmanager.js +496 -0
- package/src/dark.css +11 -0
- package/src/datamanager.js +630 -0
- package/src/datatable.js +296 -0
- package/src/defaults.js +73 -0
- package/src/dom.js +235 -0
- package/src/filterRows.js +209 -0
- package/src/icons.js +10 -0
- package/src/index.js +5 -0
- package/src/keyboard.js +59 -0
- package/src/rowmanager.js +369 -0
- package/src/style.css +304 -0
- package/src/style.js +379 -0
- package/src/translationmanager.js +30 -0
- package/src/translations/de.json +15 -0
- package/src/translations/en.json +15 -0
- package/src/translations/fr.json +15 -0
- package/src/translations/index.js +13 -0
- package/src/translations/it.json +15 -0
- package/src/utils.js +167 -0
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isNumeric,
|
|
3
|
+
nextTick,
|
|
4
|
+
isNumber,
|
|
5
|
+
notSet
|
|
6
|
+
} from './utils';
|
|
7
|
+
|
|
8
|
+
export default class DataManager {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.sortRows = nextTick(this.sortRows, this);
|
|
12
|
+
this.switchColumn = nextTick(this.switchColumn, this);
|
|
13
|
+
this.removeColumn = nextTick(this.removeColumn, this);
|
|
14
|
+
this.options.filterRows = nextTick(this.options.filterRows, this);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
init(data, columns) {
|
|
18
|
+
if (!data) {
|
|
19
|
+
data = this.options.data;
|
|
20
|
+
}
|
|
21
|
+
if (columns) {
|
|
22
|
+
this.options.columns = columns;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.data = data;
|
|
26
|
+
|
|
27
|
+
this.rowCount = 0;
|
|
28
|
+
this.columns = [];
|
|
29
|
+
this.rows = [];
|
|
30
|
+
|
|
31
|
+
this.prepareColumns();
|
|
32
|
+
this.validateData(this.data);
|
|
33
|
+
this.rows = this.prepareRows(this.data);
|
|
34
|
+
this.prepareTreeRows();
|
|
35
|
+
this.prepareRowView();
|
|
36
|
+
this.prepareNumericColumns();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// computed property
|
|
40
|
+
get currentSort() {
|
|
41
|
+
const col = this.columns.find(col => col.sortOrder !== 'none');
|
|
42
|
+
return col || {
|
|
43
|
+
colIndex: -1,
|
|
44
|
+
sortOrder: 'none'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
prepareColumns() {
|
|
49
|
+
this.columns = [];
|
|
50
|
+
this.validateColumns();
|
|
51
|
+
this.prepareDefaultColumns();
|
|
52
|
+
this.prepareHeader();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
prepareDefaultColumns() {
|
|
56
|
+
if (this.options.checkboxColumn && !this.hasColumnById('_checkbox')) {
|
|
57
|
+
const cell = {
|
|
58
|
+
id: '_checkbox',
|
|
59
|
+
content: this.getCheckboxHTML(),
|
|
60
|
+
editable: false,
|
|
61
|
+
resizable: false,
|
|
62
|
+
sortable: false,
|
|
63
|
+
focusable: false,
|
|
64
|
+
dropdown: false,
|
|
65
|
+
width: 32
|
|
66
|
+
};
|
|
67
|
+
this.columns.push(cell);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this.options.serialNoColumn && !this.hasColumnById('_rowIndex')) {
|
|
71
|
+
let cell = {
|
|
72
|
+
id: '_rowIndex',
|
|
73
|
+
content: '',
|
|
74
|
+
align: 'center',
|
|
75
|
+
editable: false,
|
|
76
|
+
resizable: false,
|
|
77
|
+
focusable: false,
|
|
78
|
+
dropdown: false
|
|
79
|
+
};
|
|
80
|
+
if (this.options.data.length > 1000) {
|
|
81
|
+
cell.resizable = true;
|
|
82
|
+
}
|
|
83
|
+
this.columns.push(cell);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
prepareHeader() {
|
|
88
|
+
let columns = this.columns.concat(this.options.columns);
|
|
89
|
+
const baseCell = {
|
|
90
|
+
isHeader: 1,
|
|
91
|
+
editable: true,
|
|
92
|
+
sortable: true,
|
|
93
|
+
resizable: true,
|
|
94
|
+
focusable: true,
|
|
95
|
+
dropdown: true,
|
|
96
|
+
width: null,
|
|
97
|
+
format: (value) => {
|
|
98
|
+
if (value === null || value === undefined) {
|
|
99
|
+
return '';
|
|
100
|
+
}
|
|
101
|
+
return value + '';
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
this.columns = columns
|
|
106
|
+
.map((cell, i) => this.prepareCell(cell, i))
|
|
107
|
+
.map(col => Object.assign({}, baseCell, col))
|
|
108
|
+
.map(col => {
|
|
109
|
+
col.content = col.content || col.name || '';
|
|
110
|
+
col.id = col.id || col.content;
|
|
111
|
+
return col;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
prepareCell(content, i) {
|
|
116
|
+
const cell = {
|
|
117
|
+
content: '',
|
|
118
|
+
sortOrder: 'none',
|
|
119
|
+
colIndex: i,
|
|
120
|
+
column: this.columns[i]
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
if (content !== null && typeof content === 'object') {
|
|
124
|
+
// passed as column/header
|
|
125
|
+
Object.assign(cell, content);
|
|
126
|
+
} else {
|
|
127
|
+
cell.content = content;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return cell;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
prepareNumericColumns() {
|
|
134
|
+
const row0 = this.getRow(0);
|
|
135
|
+
if (!row0) return;
|
|
136
|
+
this.columns = this.columns.map((column, i) => {
|
|
137
|
+
|
|
138
|
+
const cellValue = row0[i].content;
|
|
139
|
+
if (!column.align && isNumeric(cellValue)) {
|
|
140
|
+
column.align = 'right';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return column;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
prepareRows(data) {
|
|
148
|
+
return data.map((d, i) => {
|
|
149
|
+
const index = this._getNextRowCount();
|
|
150
|
+
|
|
151
|
+
let row = [];
|
|
152
|
+
let meta = {
|
|
153
|
+
rowIndex: index
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
if (Array.isArray(d)) {
|
|
157
|
+
// row is an array
|
|
158
|
+
if (this.options.checkboxColumn) {
|
|
159
|
+
row.push(this.getCheckboxHTML());
|
|
160
|
+
}
|
|
161
|
+
if (this.options.serialNoColumn) {
|
|
162
|
+
row.push((index + 1) + '');
|
|
163
|
+
}
|
|
164
|
+
row = row.concat(d);
|
|
165
|
+
|
|
166
|
+
while (row.length < this.columns.length) {
|
|
167
|
+
row.push('');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
} else {
|
|
171
|
+
// row is an object
|
|
172
|
+
for (let col of this.columns) {
|
|
173
|
+
if (col.id === '_checkbox') {
|
|
174
|
+
row.push(this.getCheckboxHTML());
|
|
175
|
+
} else if (col.id === '_rowIndex') {
|
|
176
|
+
row.push((index + 1) + '');
|
|
177
|
+
} else {
|
|
178
|
+
row.push(d[col.id]);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
meta.indent = d.indent || 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return this.prepareRow(row, meta);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
prepareTreeRows() {
|
|
190
|
+
this.rows.forEach((row, i) => {
|
|
191
|
+
if (isNumber(row.meta.indent)) {
|
|
192
|
+
// if (i === 36) debugger;
|
|
193
|
+
const nextRow = this.getRow(i + 1);
|
|
194
|
+
row.meta.isLeaf = !nextRow ||
|
|
195
|
+
notSet(nextRow.meta.indent) ||
|
|
196
|
+
nextRow.meta.indent <= row.meta.indent;
|
|
197
|
+
row.meta.isTreeNodeClose = false;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
prepareRowView() {
|
|
203
|
+
// This is order in which rows will be rendered in the table.
|
|
204
|
+
// When sorting happens, only this.rowViewOrder will change
|
|
205
|
+
// and not the original this.rows
|
|
206
|
+
this.rowViewOrder = this.rows.map(row => row.meta.rowIndex);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
prepareRow(row, meta) {
|
|
210
|
+
row = row
|
|
211
|
+
.map((cell, i) => this.prepareCell(cell, i))
|
|
212
|
+
.map(cell => {
|
|
213
|
+
// Following code is equivalent but avoids memory allocation and copying.
|
|
214
|
+
// return Object.assign({rowIndex: meta.rowIndex, indent: meta.indent}, cell)
|
|
215
|
+
if (cell.rowIndex == null) {
|
|
216
|
+
cell.rowIndex = meta.rowIndex;
|
|
217
|
+
}
|
|
218
|
+
if (cell.indent == null) {
|
|
219
|
+
cell.indent = meta.indent;
|
|
220
|
+
}
|
|
221
|
+
return cell;
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// monkey patched in array object
|
|
225
|
+
row.meta = meta;
|
|
226
|
+
return row;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
validateColumns() {
|
|
230
|
+
const columns = this.options.columns;
|
|
231
|
+
if (!Array.isArray(columns)) {
|
|
232
|
+
throw new DataError('`columns` must be an array');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
columns.forEach((column, i) => {
|
|
236
|
+
if (typeof column !== 'string' && typeof column !== 'object') {
|
|
237
|
+
throw new DataError(`column "${i}" must be a string or an object`);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
validateData(data) {
|
|
243
|
+
if (Array.isArray(data) &&
|
|
244
|
+
(data.length === 0 || Array.isArray(data[0]) || typeof data[0] === 'object')) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
throw new DataError('`data` must be an array of arrays or objects');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
appendRows(rows) {
|
|
251
|
+
this.validateData(rows);
|
|
252
|
+
this.rows = this.rows.concat(this.prepareRows(rows));
|
|
253
|
+
this.prepareTreeRows();
|
|
254
|
+
this.prepareRowView();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
sortRows(colIndex, sortOrder = 'none') {
|
|
258
|
+
colIndex = +colIndex;
|
|
259
|
+
|
|
260
|
+
// reset sortOrder and update for colIndex
|
|
261
|
+
this.getColumns()
|
|
262
|
+
.map(col => {
|
|
263
|
+
if (col.colIndex === colIndex) {
|
|
264
|
+
col.sortOrder = sortOrder;
|
|
265
|
+
} else {
|
|
266
|
+
col.sortOrder = 'none';
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
this._sortRows(colIndex, sortOrder);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
_sortRows(colIndex, sortOrder) {
|
|
274
|
+
|
|
275
|
+
if (this.currentSort.colIndex === colIndex) {
|
|
276
|
+
// reverse the array if only sortOrder changed
|
|
277
|
+
if (
|
|
278
|
+
(this.currentSort.sortOrder === 'asc' && sortOrder === 'desc') ||
|
|
279
|
+
(this.currentSort.sortOrder === 'desc' && sortOrder === 'asc')
|
|
280
|
+
) {
|
|
281
|
+
this.reverseArray(this.rowViewOrder);
|
|
282
|
+
this.currentSort.sortOrder = sortOrder;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
this.rowViewOrder.sort((a, b) => {
|
|
288
|
+
const aIndex = a;
|
|
289
|
+
const bIndex = b;
|
|
290
|
+
|
|
291
|
+
let aContent = this.getCell(colIndex, a).content;
|
|
292
|
+
let bContent = this.getCell(colIndex, b).content;
|
|
293
|
+
aContent = aContent == null ? '' : aContent;
|
|
294
|
+
bContent = bContent == null ? '' : bContent;
|
|
295
|
+
|
|
296
|
+
if (sortOrder === 'none') {
|
|
297
|
+
return aIndex - bIndex;
|
|
298
|
+
} else if (sortOrder === 'asc') {
|
|
299
|
+
if (aContent < bContent) return -1;
|
|
300
|
+
if (aContent > bContent) return 1;
|
|
301
|
+
if (aContent === bContent) return 0;
|
|
302
|
+
} else if (sortOrder === 'desc') {
|
|
303
|
+
if (aContent < bContent) return 1;
|
|
304
|
+
if (aContent > bContent) return -1;
|
|
305
|
+
if (aContent === bContent) return 0;
|
|
306
|
+
}
|
|
307
|
+
return 0;
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
if (this.hasColumnById('_rowIndex')) {
|
|
311
|
+
// update row index
|
|
312
|
+
const srNoColIndex = this.getColumnIndexById('_rowIndex');
|
|
313
|
+
this.rows.forEach((row, index) => {
|
|
314
|
+
const viewIndex = this.rowViewOrder.indexOf(index);
|
|
315
|
+
const cell = row[srNoColIndex];
|
|
316
|
+
cell.content = (viewIndex + 1) + '';
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
reverseArray(array) {
|
|
322
|
+
let left = null;
|
|
323
|
+
let right = null;
|
|
324
|
+
let length = array.length;
|
|
325
|
+
|
|
326
|
+
for (left = 0, right = length - 1; left < right; left += 1, right -= 1) {
|
|
327
|
+
const temporary = array[left];
|
|
328
|
+
|
|
329
|
+
array[left] = array[right];
|
|
330
|
+
array[right] = temporary;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
switchColumn(index1, index2) {
|
|
335
|
+
// update columns
|
|
336
|
+
const temp = this.columns[index1];
|
|
337
|
+
this.columns[index1] = this.columns[index2];
|
|
338
|
+
this.columns[index2] = temp;
|
|
339
|
+
|
|
340
|
+
this.columns[index1].colIndex = index1;
|
|
341
|
+
this.columns[index2].colIndex = index2;
|
|
342
|
+
|
|
343
|
+
// update rows
|
|
344
|
+
this.rows.forEach(row => {
|
|
345
|
+
const newCell1 = Object.assign({}, row[index1], {
|
|
346
|
+
colIndex: index2
|
|
347
|
+
});
|
|
348
|
+
const newCell2 = Object.assign({}, row[index2], {
|
|
349
|
+
colIndex: index1
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
row[index2] = newCell1;
|
|
353
|
+
row[index1] = newCell2;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
removeColumn(index) {
|
|
358
|
+
index = +index;
|
|
359
|
+
const filter = cell => cell.colIndex !== index;
|
|
360
|
+
const map = (cell, i) => Object.assign({}, cell, {
|
|
361
|
+
colIndex: i
|
|
362
|
+
});
|
|
363
|
+
// update columns
|
|
364
|
+
this.columns = this.columns
|
|
365
|
+
.filter(filter)
|
|
366
|
+
.map(map);
|
|
367
|
+
|
|
368
|
+
// update rows
|
|
369
|
+
this.rows.forEach(row => {
|
|
370
|
+
// remove cell
|
|
371
|
+
row.splice(index, 1);
|
|
372
|
+
// update colIndex
|
|
373
|
+
row.forEach((cell, i) => {
|
|
374
|
+
cell.colIndex = i;
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
updateRow(row, rowIndex) {
|
|
380
|
+
if (row.length < this.columns.length) {
|
|
381
|
+
if (this.hasColumnById('_rowIndex')) {
|
|
382
|
+
const val = (rowIndex + 1) + '';
|
|
383
|
+
|
|
384
|
+
row = [val].concat(row);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (this.hasColumnById('_checkbox')) {
|
|
388
|
+
const val = '<input type="checkbox" />';
|
|
389
|
+
|
|
390
|
+
row = [val].concat(row);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const _row = this.prepareRow(row, {rowIndex});
|
|
395
|
+
const index = this.rows.findIndex(row => row[0].rowIndex === rowIndex);
|
|
396
|
+
this.rows[index] = _row;
|
|
397
|
+
|
|
398
|
+
return _row;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
updateCell(colIndex, rowIndex, options) {
|
|
402
|
+
let cell;
|
|
403
|
+
if (typeof colIndex === 'object') {
|
|
404
|
+
// cell object was passed,
|
|
405
|
+
// must have colIndex, rowIndex
|
|
406
|
+
cell = colIndex;
|
|
407
|
+
colIndex = cell.colIndex;
|
|
408
|
+
rowIndex = cell.rowIndex;
|
|
409
|
+
// the object passed must be merged with original cell
|
|
410
|
+
options = cell;
|
|
411
|
+
}
|
|
412
|
+
cell = this.getCell(colIndex, rowIndex);
|
|
413
|
+
|
|
414
|
+
// mutate object directly
|
|
415
|
+
for (let key in options) {
|
|
416
|
+
const newVal = options[key];
|
|
417
|
+
if (newVal !== undefined) {
|
|
418
|
+
cell[key] = newVal;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return cell;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
updateColumn(colIndex, keyValPairs) {
|
|
426
|
+
const column = this.getColumn(colIndex);
|
|
427
|
+
for (let key in keyValPairs) {
|
|
428
|
+
const newVal = keyValPairs[key];
|
|
429
|
+
if (newVal !== undefined) {
|
|
430
|
+
column[key] = newVal;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return column;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
filterRows(filters) {
|
|
437
|
+
return this.options.filterRows(this.rows, filters, this)
|
|
438
|
+
.then(result => {
|
|
439
|
+
if (!result) {
|
|
440
|
+
result = this.getAllRowIndices();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (!result.then) {
|
|
444
|
+
result = Promise.resolve(result);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return result.then(rowsToShow => {
|
|
448
|
+
this._filteredRows = rowsToShow;
|
|
449
|
+
|
|
450
|
+
const rowsToHide = this.getAllRowIndices()
|
|
451
|
+
.filter(index => !rowsToShow.includes(index));
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
rowsToHide,
|
|
455
|
+
rowsToShow
|
|
456
|
+
};
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
getFilteredRowIndices() {
|
|
462
|
+
return this._filteredRows || this.getAllRowIndices();
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
getAllRowIndices() {
|
|
466
|
+
return this.rows.map(row => row.meta.rowIndex);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
getRowCount() {
|
|
470
|
+
return this.rowCount;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
_getNextRowCount() {
|
|
474
|
+
const val = this.rowCount;
|
|
475
|
+
|
|
476
|
+
this.rowCount++;
|
|
477
|
+
return val;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
getRows(start, end) {
|
|
481
|
+
return this.rows.slice(start, end);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
getRowsForView(start, end) {
|
|
485
|
+
const rows = this.rowViewOrder.map(i => this.rows[i]);
|
|
486
|
+
return rows.slice(start, end);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
getColumns(skipStandardColumns) {
|
|
490
|
+
let columns = this.columns;
|
|
491
|
+
|
|
492
|
+
if (skipStandardColumns) {
|
|
493
|
+
columns = columns.slice(this.getStandardColumnCount());
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return columns;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
getStandardColumnCount() {
|
|
500
|
+
if (this.options.checkboxColumn && this.options.serialNoColumn) {
|
|
501
|
+
return 2;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (this.options.checkboxColumn || this.options.serialNoColumn) {
|
|
505
|
+
return 1;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return 0;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
getColumnCount(skipStandardColumns) {
|
|
512
|
+
let val = this.columns.length;
|
|
513
|
+
|
|
514
|
+
if (skipStandardColumns) {
|
|
515
|
+
val = val - this.getStandardColumnCount();
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
return val;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
getColumn(colIndex) {
|
|
522
|
+
colIndex = +colIndex;
|
|
523
|
+
|
|
524
|
+
if (colIndex < 0) {
|
|
525
|
+
// negative indexes
|
|
526
|
+
colIndex = this.columns.length + colIndex;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return this.columns.find(col => col.colIndex === colIndex);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
getColumnById(id) {
|
|
533
|
+
return this.columns.find(col => col.id === id);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
getRow(rowIndex) {
|
|
537
|
+
rowIndex = +rowIndex;
|
|
538
|
+
return this.rows[rowIndex];
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
getCell(colIndex, rowIndex) {
|
|
542
|
+
rowIndex = +rowIndex;
|
|
543
|
+
colIndex = +colIndex;
|
|
544
|
+
return this.getRow(rowIndex)[colIndex];
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
getChildren(parentRowIndex) {
|
|
548
|
+
parentRowIndex = +parentRowIndex;
|
|
549
|
+
const parentIndent = this.getRow(parentRowIndex).meta.indent;
|
|
550
|
+
const out = [];
|
|
551
|
+
|
|
552
|
+
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
|
|
553
|
+
const row = this.getRow(i);
|
|
554
|
+
if (isNaN(row.meta.indent)) continue;
|
|
555
|
+
|
|
556
|
+
if (row.meta.indent > parentIndent) {
|
|
557
|
+
out.push(i);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (row.meta.indent === parentIndent) {
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return out;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
getImmediateChildren(parentRowIndex) {
|
|
569
|
+
parentRowIndex = +parentRowIndex;
|
|
570
|
+
const parentIndent = this.getRow(parentRowIndex).meta.indent;
|
|
571
|
+
const out = [];
|
|
572
|
+
const childIndent = parentIndent + 1;
|
|
573
|
+
|
|
574
|
+
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
|
|
575
|
+
const row = this.getRow(i);
|
|
576
|
+
if (isNaN(row.meta.indent) || row.meta.indent > childIndent) continue;
|
|
577
|
+
|
|
578
|
+
if (row.meta.indent === childIndent) {
|
|
579
|
+
out.push(i);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (row.meta.indent === parentIndent) {
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return out;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
get() {
|
|
591
|
+
return {
|
|
592
|
+
columns: this.columns,
|
|
593
|
+
rows: this.rows
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Returns the original data which was passed
|
|
599
|
+
* based on rowIndex
|
|
600
|
+
* @param {Number} rowIndex
|
|
601
|
+
* @returns Array|Object
|
|
602
|
+
* @memberof DataManager
|
|
603
|
+
*/
|
|
604
|
+
getData(rowIndex) {
|
|
605
|
+
return this.data[rowIndex];
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
hasColumn(name) {
|
|
609
|
+
return Boolean(this.columns.find(col => col.content === name));
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
hasColumnById(id) {
|
|
613
|
+
return Boolean(this.columns.find(col => col.id === id));
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
getColumnIndex(name) {
|
|
617
|
+
return this.columns.findIndex(col => col.content === name);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
getColumnIndexById(id) {
|
|
621
|
+
return this.columns.findIndex(col => col.id === id);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
getCheckboxHTML() {
|
|
625
|
+
return '<input type="checkbox" />';
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Custom Errors
|
|
630
|
+
export class DataError extends TypeError {};
|