@schukai/monster 3.99.1 → 3.99.3
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/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/source/components/datatable/dataset.mjs +7 -2
- package/source/components/datatable/datasource/rest.mjs +7 -7
- package/source/components/datatable/datatable/header.mjs +13 -4
- package/source/components/datatable/datatable.mjs +1141 -1152
- package/source/components/datatable/filter.mjs +1101 -1088
- package/source/components/form/action-button.mjs +1 -1
- package/source/components/form/api-button.mjs +1 -1
- package/source/components/form/button-bar.mjs +1 -1
- package/source/components/form/button.mjs +1 -1
- package/source/components/form/context-error.mjs +1 -1
- package/source/components/form/field-set.mjs +1 -1
- package/source/components/form/popper-button.mjs +274 -274
- package/source/components/form/reload.mjs +1 -1
- package/source/components/form/toggle-switch.mjs +1 -1
- package/source/components/style/form.css +8 -0
- package/source/dom/customelement.mjs +936 -946
- package/source/dom/error.mjs +59 -66
- package/source/monster.mjs +1 -0
@@ -12,79 +12,79 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {Datasource} from "./datasource.mjs";
|
15
|
+
import { Datasource } from "./datasource.mjs";
|
16
16
|
import {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
assembleMethodSymbol,
|
18
|
+
CustomElement,
|
19
|
+
registerCustomElement,
|
20
|
+
getSlottedElements,
|
21
21
|
} from "../../dom/customelement.mjs";
|
22
22
|
import {
|
23
|
-
|
24
|
-
|
23
|
+
findTargetElementFromEvent,
|
24
|
+
fireCustomEvent,
|
25
25
|
} from "../../dom/events.mjs";
|
26
|
-
import {clone} from "../../util/clone.mjs";
|
26
|
+
import { clone } from "../../util/clone.mjs";
|
27
27
|
import {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
isString,
|
29
|
+
isFunction,
|
30
|
+
isInstance,
|
31
|
+
isObject,
|
32
|
+
isArray,
|
33
33
|
} from "../../types/is.mjs";
|
34
34
|
import {
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
validateArray,
|
36
|
+
validateInteger,
|
37
|
+
validateObject,
|
38
38
|
} from "../../types/validate.mjs";
|
39
|
-
import {Observer} from "../../types/observer.mjs";
|
39
|
+
import { Observer } from "../../types/observer.mjs";
|
40
40
|
import {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
41
|
+
ATTRIBUTE_DATATABLE_HEAD,
|
42
|
+
ATTRIBUTE_DATATABLE_GRID_TEMPLATE,
|
43
|
+
ATTRIBUTE_DATASOURCE_SELECTOR,
|
44
|
+
ATTRIBUTE_DATATABLE_ALIGN,
|
45
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
46
|
+
ATTRIBUTE_DATATABLE_MODE,
|
47
|
+
ATTRIBUTE_DATATABLE_INDEX,
|
48
|
+
ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
49
|
+
ATTRIBUTE_DATATABLE_FEATURES,
|
50
|
+
ATTRIBUTE_DATATABLE_MODE_VISIBLE,
|
51
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
52
|
+
ATTRIBUTE_DATATABLE_MODE_FIXED,
|
53
53
|
} from "./constants.mjs";
|
54
|
-
import {instanceSymbol} from "../../constants.mjs";
|
54
|
+
import { instanceSymbol } from "../../constants.mjs";
|
55
55
|
import {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
Header,
|
57
|
+
createOrderStatement,
|
58
|
+
DIRECTION_ASC,
|
59
|
+
DIRECTION_DESC,
|
60
|
+
DIRECTION_NONE,
|
61
61
|
} from "./datatable/header.mjs";
|
62
|
-
import {DatatableStyleSheet} from "./stylesheet/datatable.mjs";
|
62
|
+
import { DatatableStyleSheet } from "./stylesheet/datatable.mjs";
|
63
63
|
import {
|
64
|
-
|
65
|
-
|
64
|
+
handleDataSourceChanges,
|
65
|
+
datasourceLinkedElementSymbol,
|
66
66
|
} from "./util.mjs";
|
67
67
|
import "./columnbar.mjs";
|
68
68
|
import "./filter-button.mjs";
|
69
69
|
import {
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
findElementWithSelectorUpwards,
|
71
|
+
getDocument,
|
72
|
+
getWindow,
|
73
73
|
} from "../../dom/util.mjs";
|
74
74
|
|
75
|
-
import {getDocumentTranslations} from "../../i18n/translations.mjs";
|
75
|
+
import { getDocumentTranslations } from "../../i18n/translations.mjs";
|
76
76
|
import "../state/state.mjs";
|
77
77
|
import "../host/collapse.mjs";
|
78
|
-
import {generateUniqueConfigKey} from "../host/util.mjs";
|
78
|
+
import { generateUniqueConfigKey } from "../host/util.mjs";
|
79
79
|
|
80
80
|
import "./datasource/dom.mjs";
|
81
81
|
import "./datasource/rest.mjs";
|
82
82
|
|
83
83
|
import "../form/context-help.mjs";
|
84
|
-
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
85
|
-
import {addErrorAttribute} from "../../dom/error.mjs";
|
84
|
+
import { getLocaleOfDocument } from "../../dom/locale.mjs";
|
85
|
+
import { addErrorAttribute } from "../../dom/error.mjs";
|
86
86
|
|
87
|
-
export {DataTable};
|
87
|
+
export { DataTable };
|
88
88
|
|
89
89
|
/**
|
90
90
|
* @private
|
@@ -136,6 +136,7 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
136
136
|
* @example /examples/components/datatable/datasource Use a datasource
|
137
137
|
* @example /examples/components/datatable/pagination Use pagination
|
138
138
|
* @example /examples/components/datatable/filter Filer the data
|
139
|
+
* @example /examples/components/datatable/order-by Sort data
|
139
140
|
* @example /examples/components/datatable/select-rows Select rows
|
140
141
|
*
|
141
142
|
* @copyright schukai GmbH
|
@@ -150,421 +151,412 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
150
151
|
* @fires monster-datatable-selection-changed
|
151
152
|
**/
|
152
153
|
class DataTable extends CustomElement {
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
rows.push(data);
|
560
|
-
datasource.data = c;
|
561
|
-
|
562
|
-
fireCustomEvent(this, "monster-datatable-row-added", {
|
563
|
-
index: rows.length - 1,
|
564
|
-
});
|
565
|
-
|
566
|
-
return this;
|
567
|
-
}
|
154
|
+
/**
|
155
|
+
* This method is called by the `instanceof` operator.
|
156
|
+
* @return {symbol}
|
157
|
+
*/
|
158
|
+
static get [instanceSymbol]() {
|
159
|
+
return Symbol.for("@schukai/monster/components/datatable@@instance");
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
164
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
165
|
+
*
|
166
|
+
* The individual configuration values can be found in the table.
|
167
|
+
*
|
168
|
+
* @property {Object} templates Template definitions
|
169
|
+
* @property {string} templates.main Main template
|
170
|
+
* @property {Object} datasource Datasource configuration
|
171
|
+
* @property {string} datasource.selector Selector for the datasource
|
172
|
+
* @property {string} datasource.orderDelimiter Order delimiter
|
173
|
+
* @property {Object} mapping Mapping configuration
|
174
|
+
* @property {string} mapping.data Data mapping
|
175
|
+
* @property {Array} data Data
|
176
|
+
* @property {Array} headers Headers
|
177
|
+
* @property {Object} responsive Responsive configuration
|
178
|
+
* @property {number} responsive.breakpoint Breakpoint for responsive mode
|
179
|
+
* @property {Object} labels Labels
|
180
|
+
* @property {string} labels.theListContainsNoEntries Label for empty state
|
181
|
+
* @property {Object} classes Classes
|
182
|
+
* @property {string} classes.container Container class
|
183
|
+
* @property {Object} features Features
|
184
|
+
* @property {boolean} features.settings Settings feature
|
185
|
+
* @property {boolean} features.footer Footer feature
|
186
|
+
* @property {boolean} features.autoInit Auto init feature (init datasource automatically)
|
187
|
+
* @property {boolean} features.doubleClickCopyToClipboard Double click copy to clipboard feature
|
188
|
+
* @property {boolean} features.copyAll Copy all feature
|
189
|
+
* @property {boolean} features.help Help feature
|
190
|
+
* @property {Object} templateMapping Template mapping
|
191
|
+
* @property {string} templateMapping.row-key Row key
|
192
|
+
* @property {string} templateMapping.filter-id Filter id
|
193
|
+
**/
|
194
|
+
get defaults() {
|
195
|
+
return Object.assign(
|
196
|
+
{},
|
197
|
+
super.defaults,
|
198
|
+
{
|
199
|
+
templates: {
|
200
|
+
main: getTemplate(),
|
201
|
+
emptyState: getEmptyTemplate(),
|
202
|
+
},
|
203
|
+
|
204
|
+
datasource: {
|
205
|
+
selector: null,
|
206
|
+
orderDelimiter: ",", // look at initOptionsFromArguments()
|
207
|
+
},
|
208
|
+
|
209
|
+
mapping: {
|
210
|
+
data: "dataset",
|
211
|
+
},
|
212
|
+
|
213
|
+
data: [],
|
214
|
+
headers: [],
|
215
|
+
|
216
|
+
responsive: {
|
217
|
+
breakpoint: 900,
|
218
|
+
},
|
219
|
+
|
220
|
+
labels: getTranslations(),
|
221
|
+
|
222
|
+
classes: {
|
223
|
+
control: "monster-theme-control-container-1",
|
224
|
+
container: "",
|
225
|
+
row: "monster-theme-control-row-1",
|
226
|
+
},
|
227
|
+
|
228
|
+
features: {
|
229
|
+
settings: true,
|
230
|
+
footer: true,
|
231
|
+
autoInit: true,
|
232
|
+
doubleClickCopyToClipboard: true,
|
233
|
+
copyAll: true,
|
234
|
+
help: true,
|
235
|
+
},
|
236
|
+
|
237
|
+
copy: {
|
238
|
+
delimiter: ";",
|
239
|
+
quoteOpen: '"',
|
240
|
+
quoteClose: '"',
|
241
|
+
rowBreak: "\n",
|
242
|
+
},
|
243
|
+
|
244
|
+
templateMapping: {
|
245
|
+
"row-key": null,
|
246
|
+
"filter-id": null,
|
247
|
+
},
|
248
|
+
},
|
249
|
+
initOptionsFromArguments.call(this),
|
250
|
+
);
|
251
|
+
}
|
252
|
+
|
253
|
+
/**
|
254
|
+
*
|
255
|
+
* @param {string} selector
|
256
|
+
* @return {NodeList}
|
257
|
+
*/
|
258
|
+
getGridElements(selector) {
|
259
|
+
return this[gridElementSymbol].querySelectorAll(selector);
|
260
|
+
}
|
261
|
+
|
262
|
+
/**
|
263
|
+
*
|
264
|
+
* @return {string}
|
265
|
+
*/
|
266
|
+
static getTag() {
|
267
|
+
return "monster-datatable";
|
268
|
+
}
|
269
|
+
|
270
|
+
/**
|
271
|
+
* @return {void}
|
272
|
+
*/
|
273
|
+
disconnectedCallback() {
|
274
|
+
super.disconnectedCallback();
|
275
|
+
if (this?.[resizeObserverSymbol] instanceof ResizeObserver) {
|
276
|
+
this[resizeObserverSymbol].disconnect();
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
/**
|
281
|
+
* @return {void}
|
282
|
+
*/
|
283
|
+
connectedCallback() {
|
284
|
+
const self = this;
|
285
|
+
super.connectedCallback();
|
286
|
+
|
287
|
+
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
|
288
|
+
updateGrid.call(self);
|
289
|
+
});
|
290
|
+
|
291
|
+
this[resizeObserverSymbol].observe(this.parentNode);
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* Get the row number of the selected rows as an array
|
296
|
+
*
|
297
|
+
* @returns {number[]}
|
298
|
+
*/
|
299
|
+
getSelectedRows() {
|
300
|
+
const rows = this.getGridElements(`[data-monster-role="select-row"]`);
|
301
|
+
const selectedRows = [];
|
302
|
+
rows.forEach((row) => {
|
303
|
+
if (row.checked) {
|
304
|
+
const key = row.parentNode.getAttribute(
|
305
|
+
"data-monster-insert-reference",
|
306
|
+
);
|
307
|
+
const index = key.split("-").pop();
|
308
|
+
selectedRows.push(parseInt(index, 10));
|
309
|
+
}
|
310
|
+
});
|
311
|
+
|
312
|
+
return selectedRows;
|
313
|
+
}
|
314
|
+
|
315
|
+
/**
|
316
|
+
* @return void
|
317
|
+
*/
|
318
|
+
[assembleMethodSymbol]() {
|
319
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
320
|
+
|
321
|
+
if (rawKey === null) {
|
322
|
+
if (this.id !== null && this.id !== "") {
|
323
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
324
|
+
if (rawKey === null) {
|
325
|
+
this.setOption("templateMapping.row-key", this.id + "-row");
|
326
|
+
}
|
327
|
+
} else {
|
328
|
+
this.setOption("templateMapping.row-key", "row");
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
if (this.id !== null && this.id !== "") {
|
333
|
+
this.setOption("templateMapping.filter-id", "" + this.id + "-filter");
|
334
|
+
} else {
|
335
|
+
this.setOption("templateMapping.filter-id", "filter");
|
336
|
+
}
|
337
|
+
|
338
|
+
super[assembleMethodSymbol]();
|
339
|
+
|
340
|
+
initControlReferences.call(this);
|
341
|
+
initEventHandler.call(this);
|
342
|
+
|
343
|
+
getHostConfig
|
344
|
+
.call(this, getColumnVisibilityConfigKey)
|
345
|
+
.then((config) => {
|
346
|
+
const headerOrderMap = new Map();
|
347
|
+
|
348
|
+
getHostConfig
|
349
|
+
.call(this, getStoredOrderConfigKey)
|
350
|
+
.then((orderConfig) => {
|
351
|
+
if (isArray(orderConfig) || orderConfig.length > 0) {
|
352
|
+
for (let i = 0; i < orderConfig.length; i++) {
|
353
|
+
const item = orderConfig[i];
|
354
|
+
const parts = item.split(" ");
|
355
|
+
const field = parts[0];
|
356
|
+
const direction = parts[1] || DIRECTION_ASC;
|
357
|
+
headerOrderMap.set(field, direction);
|
358
|
+
}
|
359
|
+
}
|
360
|
+
})
|
361
|
+
.then(() => {
|
362
|
+
try {
|
363
|
+
initGridAndStructs.call(this, config, headerOrderMap);
|
364
|
+
} catch (error) {
|
365
|
+
addErrorAttribute(this, error);
|
366
|
+
}
|
367
|
+
|
368
|
+
updateColumnBar.call(this);
|
369
|
+
})
|
370
|
+
.catch((error) => {
|
371
|
+
addErrorAttribute(this, error);
|
372
|
+
});
|
373
|
+
})
|
374
|
+
.catch((error) => {
|
375
|
+
addErrorAttribute(this, error);
|
376
|
+
})
|
377
|
+
.finally(() => {
|
378
|
+
const selector = this.getOption("datasource.selector");
|
379
|
+
|
380
|
+
if (isString(selector)) {
|
381
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
382
|
+
if (element === null) {
|
383
|
+
throw new Error("the selector must match exactly one element");
|
384
|
+
}
|
385
|
+
|
386
|
+
if (!isInstance(element, Datasource)) {
|
387
|
+
throw new TypeError("the element must be a datasource");
|
388
|
+
}
|
389
|
+
|
390
|
+
this[datasourceLinkedElementSymbol] = element;
|
391
|
+
|
392
|
+
getWindow().requestAnimationFrame(() => {
|
393
|
+
handleDataSourceChanges.call(this);
|
394
|
+
if (element && "datasource" in element) {
|
395
|
+
element.datasource.attachObserver(
|
396
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
397
|
+
);
|
398
|
+
}
|
399
|
+
});
|
400
|
+
}
|
401
|
+
});
|
402
|
+
}
|
403
|
+
|
404
|
+
/**
|
405
|
+
* @return {CSSStyleSheet[]}
|
406
|
+
*/
|
407
|
+
static getCSSStyleSheet() {
|
408
|
+
return [DatatableStyleSheet];
|
409
|
+
}
|
410
|
+
|
411
|
+
/**
|
412
|
+
* Copy a row from the datatable
|
413
|
+
*
|
414
|
+
* @param {number|string} fromIndex
|
415
|
+
* @param {number|string} toIndex
|
416
|
+
* @return {DataTable}
|
417
|
+
* @fires monster-datatable-row-copied
|
418
|
+
*/
|
419
|
+
copyRow(fromIndex, toIndex) {
|
420
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
421
|
+
if (!datasource) {
|
422
|
+
return this;
|
423
|
+
}
|
424
|
+
let d = datasource.data;
|
425
|
+
let c = clone(d);
|
426
|
+
|
427
|
+
let rows = c;
|
428
|
+
const mapping = this.getOption("mapping.data");
|
429
|
+
|
430
|
+
if (mapping) {
|
431
|
+
rows = c?.[mapping];
|
432
|
+
}
|
433
|
+
|
434
|
+
if (rows === undefined || rows === null) {
|
435
|
+
rows = [];
|
436
|
+
}
|
437
|
+
|
438
|
+
if (toIndex === undefined) {
|
439
|
+
toIndex = rows.length;
|
440
|
+
}
|
441
|
+
|
442
|
+
if (isString(fromIndex)) {
|
443
|
+
fromIndex = parseInt(fromIndex);
|
444
|
+
}
|
445
|
+
if (isString(toIndex)) {
|
446
|
+
toIndex = parseInt(toIndex);
|
447
|
+
}
|
448
|
+
|
449
|
+
if (toIndex < 0 || toIndex > rows.length) {
|
450
|
+
throw new RangeError("index out of bounds");
|
451
|
+
}
|
452
|
+
|
453
|
+
validateArray(rows);
|
454
|
+
validateInteger(fromIndex);
|
455
|
+
validateInteger(toIndex);
|
456
|
+
|
457
|
+
if (fromIndex < 0 || fromIndex >= rows.length) {
|
458
|
+
throw new RangeError("index out of bounds");
|
459
|
+
}
|
460
|
+
|
461
|
+
rows.splice(toIndex, 0, clone(rows[fromIndex]));
|
462
|
+
datasource.data = c;
|
463
|
+
|
464
|
+
fireCustomEvent(this, "monster-datatable-row-copied", {
|
465
|
+
index: toIndex,
|
466
|
+
});
|
467
|
+
|
468
|
+
return this;
|
469
|
+
}
|
470
|
+
|
471
|
+
/**
|
472
|
+
* Remove a row from the datatable
|
473
|
+
*
|
474
|
+
* @param {number|string} index
|
475
|
+
* @return {DataTable}
|
476
|
+
* @fires monster-datatable-row-removed
|
477
|
+
*/
|
478
|
+
removeRow(index) {
|
479
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
480
|
+
if (!datasource) {
|
481
|
+
return this;
|
482
|
+
}
|
483
|
+
let d = datasource.data;
|
484
|
+
let c = clone(d);
|
485
|
+
|
486
|
+
let rows = c;
|
487
|
+
const mapping = this.getOption("mapping.data");
|
488
|
+
|
489
|
+
if (mapping) {
|
490
|
+
rows = c?.[mapping];
|
491
|
+
}
|
492
|
+
|
493
|
+
if (rows === undefined || rows === null) {
|
494
|
+
rows = [];
|
495
|
+
}
|
496
|
+
|
497
|
+
if (isString(index)) {
|
498
|
+
index = parseInt(index);
|
499
|
+
}
|
500
|
+
|
501
|
+
validateArray(rows);
|
502
|
+
validateInteger(index);
|
503
|
+
|
504
|
+
if (index < 0 || index >= rows.length) {
|
505
|
+
throw new RangeError("index out of bounds");
|
506
|
+
}
|
507
|
+
if (mapping) {
|
508
|
+
rows = c?.[mapping];
|
509
|
+
}
|
510
|
+
|
511
|
+
rows.splice(index, 1);
|
512
|
+
datasource.data = c;
|
513
|
+
|
514
|
+
fireCustomEvent(this, "monster-datatable-row-removed", {
|
515
|
+
index: index,
|
516
|
+
});
|
517
|
+
|
518
|
+
return this;
|
519
|
+
}
|
520
|
+
|
521
|
+
/**
|
522
|
+
* Add a row to the datatable
|
523
|
+
*
|
524
|
+
* @param {Object} data
|
525
|
+
* @return {DataTable}
|
526
|
+
*
|
527
|
+
* @fires monster-datatable-row-added
|
528
|
+
**/
|
529
|
+
addRow(data) {
|
530
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
531
|
+
if (!datasource) {
|
532
|
+
return this;
|
533
|
+
}
|
534
|
+
let d = datasource.data;
|
535
|
+
let c = clone(d);
|
536
|
+
|
537
|
+
let rows = c;
|
538
|
+
|
539
|
+
const mapping = this.getOption("mapping.data");
|
540
|
+
if (mapping) {
|
541
|
+
rows = c?.[mapping];
|
542
|
+
}
|
543
|
+
|
544
|
+
if (rows === undefined || rows === null) {
|
545
|
+
rows = [];
|
546
|
+
}
|
547
|
+
|
548
|
+
validateArray(rows);
|
549
|
+
validateObject(data);
|
550
|
+
|
551
|
+
rows.push(data);
|
552
|
+
datasource.data = c;
|
553
|
+
|
554
|
+
fireCustomEvent(this, "monster-datatable-row-added", {
|
555
|
+
index: rows.length - 1,
|
556
|
+
});
|
557
|
+
|
558
|
+
return this;
|
559
|
+
}
|
568
560
|
}
|
569
561
|
|
570
562
|
/**
|
@@ -572,7 +564,7 @@ class DataTable extends CustomElement {
|
|
572
564
|
* @return {string}
|
573
565
|
*/
|
574
566
|
function getColumnVisibilityConfigKey() {
|
575
|
-
|
567
|
+
return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
|
576
568
|
}
|
577
569
|
|
578
570
|
/**
|
@@ -580,7 +572,7 @@ function getColumnVisibilityConfigKey() {
|
|
580
572
|
* @return {string}
|
581
573
|
*/
|
582
574
|
function getFilterConfigKey() {
|
583
|
-
|
575
|
+
return generateUniqueConfigKey("datatable", this?.id, "filter");
|
584
576
|
}
|
585
577
|
|
586
578
|
/**
|
@@ -588,537 +580,530 @@ function getFilterConfigKey() {
|
|
588
580
|
* @return {Promise}
|
589
581
|
*/
|
590
582
|
function getHostConfig(callback) {
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
return {};
|
616
|
-
}
|
617
|
-
});
|
583
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
584
|
+
|
585
|
+
if (!host) {
|
586
|
+
addErrorAttribute(this, "no host found");
|
587
|
+
return Promise.resolve({});
|
588
|
+
}
|
589
|
+
|
590
|
+
if (!this.id) {
|
591
|
+
addErrorAttribute(this, "no id found; id is required for config");
|
592
|
+
return Promise.resolve({});
|
593
|
+
}
|
594
|
+
|
595
|
+
if (!host || !isFunction(host?.getConfig)) {
|
596
|
+
throw new TypeError("the host must be a monster-host");
|
597
|
+
}
|
598
|
+
|
599
|
+
const configKey = callback.call(this);
|
600
|
+
return host.hasConfig(configKey).then((hasConfig) => {
|
601
|
+
if (hasConfig) {
|
602
|
+
return host.getConfig(configKey);
|
603
|
+
} else {
|
604
|
+
return {};
|
605
|
+
}
|
606
|
+
});
|
618
607
|
}
|
619
608
|
|
620
609
|
/**
|
621
610
|
* @private
|
622
611
|
*/
|
623
612
|
function updateColumnBar() {
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
613
|
+
if (!this[columnBarElementSymbol]) {
|
614
|
+
return;
|
615
|
+
}
|
616
|
+
|
617
|
+
const columns = [];
|
618
|
+
for (const header of this.getOption("headers")) {
|
619
|
+
const mode = header.getInternal("mode");
|
620
|
+
|
621
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
622
|
+
continue;
|
623
|
+
}
|
624
|
+
|
625
|
+
columns.push({
|
626
|
+
visible: mode !== ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
627
|
+
name: header.label,
|
628
|
+
index: header.index,
|
629
|
+
});
|
630
|
+
}
|
631
|
+
|
632
|
+
this[columnBarElementSymbol].setOption("columns", columns);
|
644
633
|
}
|
645
634
|
|
646
635
|
/**
|
647
636
|
* @private
|
648
637
|
*/
|
649
638
|
function updateHeaderFromColumnBar() {
|
650
|
-
|
651
|
-
|
652
|
-
|
639
|
+
if (!this[columnBarElementSymbol]) {
|
640
|
+
return;
|
641
|
+
}
|
653
642
|
|
654
|
-
|
655
|
-
|
643
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
644
|
+
if (!isArray(options)) return;
|
656
645
|
|
657
|
-
|
646
|
+
const invisibleMap = {};
|
658
647
|
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
648
|
+
for (let i = 0; i < options.length; i++) {
|
649
|
+
const option = options[i];
|
650
|
+
invisibleMap[option.index] = option.visible;
|
651
|
+
}
|
663
652
|
|
664
|
-
|
665
|
-
|
653
|
+
for (const header of this.getOption("headers")) {
|
654
|
+
const mode = header.getInternal("mode");
|
666
655
|
|
667
|
-
|
668
|
-
|
669
|
-
|
656
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
657
|
+
continue;
|
658
|
+
}
|
670
659
|
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
660
|
+
if (invisibleMap[header.index] === false) {
|
661
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_HIDDEN);
|
662
|
+
} else {
|
663
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_VISIBLE);
|
664
|
+
}
|
665
|
+
}
|
677
666
|
}
|
678
667
|
|
679
668
|
/**
|
680
669
|
* @private
|
681
670
|
*/
|
682
671
|
function updateConfigColumnBar() {
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
672
|
+
if (!this[columnBarElementSymbol]) {
|
673
|
+
return;
|
674
|
+
}
|
675
|
+
|
676
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
677
|
+
if (!isArray(options)) return;
|
678
|
+
|
679
|
+
const map = {};
|
680
|
+
for (let i = 0; i < options.length; i++) {
|
681
|
+
const option = options[i];
|
682
|
+
map[option.name] = option.visible;
|
683
|
+
}
|
684
|
+
|
685
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
686
|
+
if (!(host && this.id)) {
|
687
|
+
return;
|
688
|
+
}
|
689
|
+
const configKey = getColumnVisibilityConfigKey.call(this);
|
690
|
+
|
691
|
+
try {
|
692
|
+
host.setConfig(configKey, map);
|
693
|
+
} catch (error) {
|
694
|
+
addErrorAttribute(this, error);
|
695
|
+
}
|
707
696
|
}
|
708
697
|
|
709
698
|
/**
|
710
699
|
* @private
|
711
700
|
*/
|
712
701
|
function initEventHandler() {
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
}
|
956
|
-
};
|
957
|
-
|
958
|
-
this[gridHeadersElementSymbol].addEventListener("click", selectAllCallback);
|
959
|
-
this[gridHeadersElementSymbol].addEventListener("touch", selectAllCallback);
|
702
|
+
const self = this;
|
703
|
+
|
704
|
+
const quoteOpenChar = this.getOption("copy.quoteOpen");
|
705
|
+
const quoteCloseChar = this.getOption("copy.quoteClose");
|
706
|
+
const delimiterChar = this.getOption("copy.delimiter");
|
707
|
+
const rowBreak = this.getOption("copy.rowBreak");
|
708
|
+
|
709
|
+
self[columnBarElementSymbol].attachObserver(
|
710
|
+
new Observer((e) => {
|
711
|
+
updateHeaderFromColumnBar.call(self);
|
712
|
+
updateGrid.call(self);
|
713
|
+
updateConfigColumnBar.call(self);
|
714
|
+
}),
|
715
|
+
);
|
716
|
+
|
717
|
+
self[gridHeadersElementSymbol].addEventListener("click", function (event) {
|
718
|
+
let element = null;
|
719
|
+
const datasource = self[datasourceLinkedElementSymbol];
|
720
|
+
if (!datasource) {
|
721
|
+
return;
|
722
|
+
}
|
723
|
+
|
724
|
+
element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
|
725
|
+
if (element instanceof HTMLElement) {
|
726
|
+
const index = element.parentNode?.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
|
727
|
+
const headers = self.getOption("headers");
|
728
|
+
|
729
|
+
event.preventDefault();
|
730
|
+
|
731
|
+
headers[index].changeDirection();
|
732
|
+
|
733
|
+
queueMicrotask(function () {
|
734
|
+
/** hotfix, normally this should be done via the updater, no idea why this is not possible. */
|
735
|
+
element.setAttribute(
|
736
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
737
|
+
`${headers[index].field} ${headers[index].direction}`,
|
738
|
+
);
|
739
|
+
|
740
|
+
storeOrderStatement.call(self, true);
|
741
|
+
});
|
742
|
+
}
|
743
|
+
});
|
744
|
+
|
745
|
+
const eventHandlerDoubleClickCopyToClipboard = (event) => {
|
746
|
+
const element = findTargetElementFromEvent(event, "data-monster-head");
|
747
|
+
if (element) {
|
748
|
+
let text = "";
|
749
|
+
|
750
|
+
if (event.shiftKey) {
|
751
|
+
const index = element.getAttribute("data-monster-insert-reference");
|
752
|
+
if (index) {
|
753
|
+
const cols = self.getGridElements(
|
754
|
+
`[data-monster-insert-reference="${index}"]`,
|
755
|
+
);
|
756
|
+
|
757
|
+
const colTexts = [];
|
758
|
+
for (let i = 0; i < cols.length; i++) {
|
759
|
+
const col = cols[i];
|
760
|
+
|
761
|
+
if (
|
762
|
+
col.querySelector("monster-button-bar") ||
|
763
|
+
col.querySelector("monster-button")
|
764
|
+
) {
|
765
|
+
continue;
|
766
|
+
}
|
767
|
+
|
768
|
+
if (col.textContent) {
|
769
|
+
colTexts.push(
|
770
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
771
|
+
);
|
772
|
+
}
|
773
|
+
}
|
774
|
+
|
775
|
+
text = colTexts.join(delimiterChar);
|
776
|
+
}
|
777
|
+
} else {
|
778
|
+
if (
|
779
|
+
element.querySelector("monster-button-bar") ||
|
780
|
+
element.querySelector("monster-button")
|
781
|
+
) {
|
782
|
+
return;
|
783
|
+
}
|
784
|
+
|
785
|
+
text = element.textContent.trim();
|
786
|
+
}
|
787
|
+
|
788
|
+
if (getWindow().navigator.clipboard && text) {
|
789
|
+
getWindow()
|
790
|
+
.navigator.clipboard.writeText(text)
|
791
|
+
.then(
|
792
|
+
() => {},
|
793
|
+
(err) => {},
|
794
|
+
);
|
795
|
+
}
|
796
|
+
}
|
797
|
+
};
|
798
|
+
|
799
|
+
if (self.getOption("features.doubleClickCopyToClipboard")) {
|
800
|
+
self[gridElementSymbol].addEventListener(
|
801
|
+
"dblclick",
|
802
|
+
eventHandlerDoubleClickCopyToClipboard,
|
803
|
+
);
|
804
|
+
}
|
805
|
+
|
806
|
+
if (self.getOption("features.copyAll") && this[copyAllElementSymbol]) {
|
807
|
+
this[copyAllElementSymbol].addEventListener("click", (event) => {
|
808
|
+
event.preventDefault();
|
809
|
+
|
810
|
+
const table = [];
|
811
|
+
let currentRow = [];
|
812
|
+
let currentIndex = null;
|
813
|
+
|
814
|
+
const cols = self.getGridElements(`[data-monster-insert-reference]`);
|
815
|
+
const rowIndexes = new Map();
|
816
|
+
cols.forEach((col) => {
|
817
|
+
const index = col.getAttribute("data-monster-insert-reference");
|
818
|
+
rowIndexes.set(index, true);
|
819
|
+
});
|
820
|
+
|
821
|
+
rowIndexes.forEach((value, key) => {
|
822
|
+
const cols = self.getGridElements(
|
823
|
+
`[data-monster-insert-reference="${key}"]`,
|
824
|
+
);
|
825
|
+
|
826
|
+
for (let i = 0; i < cols.length; i++) {
|
827
|
+
const col = cols[i];
|
828
|
+
|
829
|
+
if (
|
830
|
+
col.querySelector("monster-button-bar") ||
|
831
|
+
col.querySelector("monster-button")
|
832
|
+
) {
|
833
|
+
continue;
|
834
|
+
}
|
835
|
+
|
836
|
+
if (col.textContent) {
|
837
|
+
currentRow.push(
|
838
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
839
|
+
);
|
840
|
+
}
|
841
|
+
}
|
842
|
+
|
843
|
+
if (currentRow.length > 0) {
|
844
|
+
table.push(currentRow);
|
845
|
+
}
|
846
|
+
currentRow = [];
|
847
|
+
});
|
848
|
+
|
849
|
+
if (table.length > 0) {
|
850
|
+
const text = table.map((row) => row.join(delimiterChar)).join(rowBreak);
|
851
|
+
if (getWindow().navigator.clipboard && text) {
|
852
|
+
getWindow()
|
853
|
+
.navigator.clipboard.writeText(text)
|
854
|
+
.then(
|
855
|
+
() => {},
|
856
|
+
(err) => {},
|
857
|
+
);
|
858
|
+
}
|
859
|
+
}
|
860
|
+
});
|
861
|
+
}
|
862
|
+
|
863
|
+
const selectRowCallback = (event) => {
|
864
|
+
const element = findTargetElementFromEvent(
|
865
|
+
event,
|
866
|
+
"data-monster-role",
|
867
|
+
"select-row",
|
868
|
+
);
|
869
|
+
|
870
|
+
if (!element) {
|
871
|
+
return;
|
872
|
+
}
|
873
|
+
|
874
|
+
const key = element.parentNode.getAttribute(
|
875
|
+
"data-monster-insert-reference",
|
876
|
+
);
|
877
|
+
const row = self.getGridElements(
|
878
|
+
`[data-monster-insert-reference="${key}"]`,
|
879
|
+
);
|
880
|
+
|
881
|
+
const index = key.split("-").pop();
|
882
|
+
|
883
|
+
if (element.checked) {
|
884
|
+
row.forEach((col) => {
|
885
|
+
col.classList.add("selected");
|
886
|
+
});
|
887
|
+
|
888
|
+
fireCustomEvent(self, "monster-datatable-row-selected", {
|
889
|
+
index: index,
|
890
|
+
});
|
891
|
+
} else {
|
892
|
+
row.forEach((col) => {
|
893
|
+
col.classList.remove("selected");
|
894
|
+
});
|
895
|
+
|
896
|
+
fireCustomEvent(self, "monster-datatable-row-deselected", {
|
897
|
+
index: index,
|
898
|
+
});
|
899
|
+
}
|
900
|
+
|
901
|
+
fireCustomEvent(this, "monster-datatable-selection-changed", {});
|
902
|
+
|
903
|
+
const rows = self.getGridElements(`[data-monster-role="select-row"]`);
|
904
|
+
const allSelected = Array.from(rows).every((row) => row.checked);
|
905
|
+
|
906
|
+
const selectAll = this[gridHeadersElementSymbol].querySelector(
|
907
|
+
`[data-monster-role="select-all"]`,
|
908
|
+
);
|
909
|
+
|
910
|
+
if (selectAll) {
|
911
|
+
selectAll.checked = allSelected;
|
912
|
+
}
|
913
|
+
};
|
914
|
+
|
915
|
+
this[gridElementSymbol].addEventListener("click", selectRowCallback);
|
916
|
+
this[gridElementSymbol].addEventListener("touch", selectRowCallback);
|
917
|
+
|
918
|
+
const selectAllCallback = (event) => {
|
919
|
+
const element = findTargetElementFromEvent(
|
920
|
+
event,
|
921
|
+
"data-monster-role",
|
922
|
+
"select-all",
|
923
|
+
);
|
924
|
+
if (element) {
|
925
|
+
const mode = element.checked;
|
926
|
+
|
927
|
+
const rows = this.getGridElements(`[data-monster-role="select-row"]`);
|
928
|
+
rows.forEach((row) => {
|
929
|
+
row.checked = mode;
|
930
|
+
});
|
931
|
+
|
932
|
+
if (mode) {
|
933
|
+
fireCustomEvent(this, "monster-datatable-all-rows-selected", {});
|
934
|
+
} else {
|
935
|
+
fireCustomEvent(this, "monster-datatable-all-rows-deselected", {});
|
936
|
+
}
|
937
|
+
|
938
|
+
fireCustomEvent(this, "monster-datatable-selection-changed", {});
|
939
|
+
}
|
940
|
+
};
|
941
|
+
|
942
|
+
this[gridHeadersElementSymbol].addEventListener("click", selectAllCallback);
|
943
|
+
this[gridHeadersElementSymbol].addEventListener("touch", selectAllCallback);
|
960
944
|
}
|
961
945
|
|
962
946
|
/**
|
963
947
|
* @private
|
964
948
|
*/
|
965
949
|
function initGridAndStructs(hostConfig, headerOrderMap) {
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
950
|
+
const rowID = this.getOption("templateMapping.row-key");
|
951
|
+
|
952
|
+
if (!this[gridElementSymbol]) {
|
953
|
+
addErrorAttribute(this, "no grid element found");
|
954
|
+
return;
|
955
|
+
}
|
956
|
+
|
957
|
+
let template;
|
958
|
+
getSlottedElements.call(this).forEach((e) => {
|
959
|
+
if (e instanceof HTMLTemplateElement && e.id === rowID) {
|
960
|
+
template = e;
|
961
|
+
}
|
962
|
+
});
|
963
|
+
|
964
|
+
if (!template) {
|
965
|
+
addErrorAttribute(this, "no template found, please add a template");
|
966
|
+
return;
|
967
|
+
}
|
968
|
+
|
969
|
+
const rowCount = template.content.children.length;
|
970
|
+
|
971
|
+
const headers = [];
|
972
|
+
|
973
|
+
for (let i = 0; i < rowCount; i++) {
|
974
|
+
let hClass = "";
|
975
|
+
const row = template.content.children[i];
|
976
|
+
|
977
|
+
let mode = "";
|
978
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_MODE)) {
|
979
|
+
mode = row.getAttribute(ATTRIBUTE_DATATABLE_MODE);
|
980
|
+
}
|
981
|
+
|
982
|
+
let grid = row.getAttribute(ATTRIBUTE_DATATABLE_GRID_TEMPLATE);
|
983
|
+
if (!grid || grid === "" || grid === "auto") {
|
984
|
+
grid = "minmax(0, 1fr)";
|
985
|
+
}
|
986
|
+
|
987
|
+
let label = "";
|
988
|
+
let labelKey = "";
|
989
|
+
|
990
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_HEAD)) {
|
991
|
+
label = row.getAttribute(ATTRIBUTE_DATATABLE_HEAD);
|
992
|
+
labelKey = label;
|
993
|
+
|
994
|
+
try {
|
995
|
+
if (label.startsWith("i18n:")) {
|
996
|
+
label = label.substring(5, label.length);
|
997
|
+
label = getDocumentTranslations().getText(label, label);
|
998
|
+
}
|
999
|
+
} catch (e) {
|
1000
|
+
label = "i18n error " + label;
|
1001
|
+
}
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
if (!label) {
|
1005
|
+
label = i + 1 + "";
|
1006
|
+
mode = ATTRIBUTE_DATATABLE_MODE_FIXED;
|
1007
|
+
labelKey = label;
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
if (isObject(hostConfig) && hostConfig.hasOwnProperty(label)) {
|
1011
|
+
if (hostConfig[label] === false) {
|
1012
|
+
mode = ATTRIBUTE_DATATABLE_MODE_HIDDEN;
|
1013
|
+
} else {
|
1014
|
+
mode = ATTRIBUTE_DATATABLE_MODE_VISIBLE;
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
let align = "";
|
1019
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_ALIGN)) {
|
1020
|
+
align = row.getAttribute(ATTRIBUTE_DATATABLE_ALIGN);
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
switch (align) {
|
1024
|
+
case "center":
|
1025
|
+
hClass = "flex-center";
|
1026
|
+
break;
|
1027
|
+
case "end":
|
1028
|
+
hClass = "flex-end";
|
1029
|
+
break;
|
1030
|
+
case "start":
|
1031
|
+
hClass = "flex-start";
|
1032
|
+
break;
|
1033
|
+
default:
|
1034
|
+
hClass = "flex-start";
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
let field = "";
|
1038
|
+
let direction = DIRECTION_NONE;
|
1039
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_SORTABLE)) {
|
1040
|
+
field = row.getAttribute(ATTRIBUTE_DATATABLE_SORTABLE).trim();
|
1041
|
+
const parts = field.split(" ").map((item) => item.trim());
|
1042
|
+
field = parts[0];
|
1043
|
+
|
1044
|
+
if (headerOrderMap.has(field)) {
|
1045
|
+
direction = headerOrderMap.get(field);
|
1046
|
+
} else if (
|
1047
|
+
parts.length === 2 &&
|
1048
|
+
[DIRECTION_ASC, DIRECTION_DESC].indexOf(parts[1]) !== -1
|
1049
|
+
) {
|
1050
|
+
direction = parts[1];
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
1055
|
+
hClass += " hidden";
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
const features = [];
|
1059
|
+
|
1060
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_FEATURES)) {
|
1061
|
+
const fl = row.getAttribute(ATTRIBUTE_DATATABLE_FEATURES).split(" ");
|
1062
|
+
|
1063
|
+
fl.forEach((feature) => {
|
1064
|
+
features.push(feature.trim());
|
1065
|
+
|
1066
|
+
if (feature === "select") {
|
1067
|
+
label = "<input type='checkbox' data-monster-role='select-all' />";
|
1068
|
+
|
1069
|
+
while (row.firstChild) {
|
1070
|
+
row.removeChild(row.firstChild);
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
const checkbox = document.createElement("input");
|
1074
|
+
checkbox.type = "checkbox";
|
1075
|
+
checkbox.setAttribute("data-monster-role", "select-row");
|
1076
|
+
row.appendChild(checkbox);
|
1077
|
+
}
|
1078
|
+
});
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
let orderTemplate = "${field} ${direction}";
|
1082
|
+
if (row.hasAttribute("data-monster-order-template")) {
|
1083
|
+
orderTemplate = row.getAttribute("data-monster-order-template");
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
const header = new Header();
|
1087
|
+
header.setInternals({
|
1088
|
+
field: field,
|
1089
|
+
label: label,
|
1090
|
+
classes: hClass,
|
1091
|
+
index: i,
|
1092
|
+
mode: mode,
|
1093
|
+
grid: grid,
|
1094
|
+
labelKey: labelKey,
|
1095
|
+
direction: direction,
|
1096
|
+
features: features,
|
1097
|
+
orderTemplate: orderTemplate
|
1098
|
+
});
|
1099
|
+
|
1100
|
+
headers.push(header);
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
this.setOption("headers", headers);
|
1104
|
+
queueMicrotask(() => {
|
1105
|
+
storeOrderStatement.call(this, this.getOption("features.autoInit"));
|
1106
|
+
});
|
1122
1107
|
}
|
1123
1108
|
|
1124
1109
|
/**
|
@@ -1126,101 +1111,101 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
1126
1111
|
* @returns {object}
|
1127
1112
|
*/
|
1128
1113
|
function getTranslations() {
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1114
|
+
const locale = getLocaleOfDocument();
|
1115
|
+
switch (locale.language) {
|
1116
|
+
case "de":
|
1117
|
+
return {
|
1118
|
+
theListContainsNoEntries: "Die Liste enthält keine Einträge",
|
1119
|
+
copyAll: "Alles kopieren",
|
1120
|
+
helpText:
|
1121
|
+
"<p>Sie können die Werte aus einzelnen Zeilen<br>" +
|
1122
|
+
"in die Zwischenablage kopieren, indem Sie auf die entsprechende Spalte doppelklicken.</p>" +
|
1123
|
+
"<p>Um eine ganze Zeile zu kopieren, halten Sie die Umschalttaste gedrückt, während Sie klicken.<br>" +
|
1124
|
+
"Wenn Sie alle Zeilen kopieren möchten, können Sie die Schaltfläche <strong>Alles kopieren</strong> verwenden.</p>",
|
1125
|
+
};
|
1126
|
+
case "fr":
|
1127
|
+
return {
|
1128
|
+
theListContainsNoEntries: "La liste ne contient aucune entrée",
|
1129
|
+
copyAll: "Copier tout",
|
1130
|
+
helpText:
|
1131
|
+
"<p>Vous pouvez copier les valeurs des rangées individuelles<br>" +
|
1132
|
+
"dans le presse-papiers en double-cliquant sur la colonne concernée.</p>" +
|
1133
|
+
"<p>Pour copier une rangée entière, maintenez la touche Maj enfoncée tout en cliquant.<br>" +
|
1134
|
+
"Si vous souhaitez copier toutes les rangées, vous pouvez utiliser le bouton <strong>Copier tout</strong>.</p>",
|
1135
|
+
};
|
1136
|
+
case "sp":
|
1137
|
+
return {
|
1138
|
+
theListContainsNoEntries: "La lista no contiene entradas",
|
1139
|
+
copyAll: "Copiar todo",
|
1140
|
+
helpText:
|
1141
|
+
"<p>Puedes copiar los valores de filas individuales<br>" +
|
1142
|
+
"al portapapeles haciendo doble clic en la columna correspondiente.</p>" +
|
1143
|
+
"<p>Para copiar una fila entera, mantén presionada la tecla Shift mientras haces clic.<br>" +
|
1144
|
+
"Si quieres copiar todas las filas, puedes usar el botón <strong>Copiar todo</strong>.</p>",
|
1145
|
+
};
|
1146
|
+
case "it":
|
1147
|
+
return {
|
1148
|
+
theListContainsNoEntries: "L'elenco non contiene voci",
|
1149
|
+
copyAll: "Copia tutto",
|
1150
|
+
helpText:
|
1151
|
+
"<p>Puoi copiare i valori dalle singole righe<br>" +
|
1152
|
+
"negli appunti facendo doppio clic sulla colonna relativa.</p>" +
|
1153
|
+
"<p>Per copiare un'intera riga, tieni premuto il tasto Shift mentre clicchi.<br>" +
|
1154
|
+
"Se vuoi copiare tutte le righe, puoi usare il pulsante <strong>Copia tutto</strong>.</p>",
|
1155
|
+
};
|
1156
|
+
case "pl":
|
1157
|
+
return {
|
1158
|
+
theListContainsNoEntries: "Lista nie zawiera wpisów",
|
1159
|
+
copyAll: "Kopiuj wszystko",
|
1160
|
+
helpText:
|
1161
|
+
"<p>Możesz skopiować wartości z poszczególnych wierszy<br>" +
|
1162
|
+
"do schowka, klikając dwukrotnie na odpowiednią kolumnę.</p>" +
|
1163
|
+
"<p>Aby skopiować cały wiersz, przytrzymaj klawisz Shift podczas klikania.<br>" +
|
1164
|
+
"Jeśli chcesz skopiować wszystkie wiersze, możesz użyć przycisku <strong>Kopiuj wszystko</strong>.</p>",
|
1165
|
+
};
|
1166
|
+
case "no":
|
1167
|
+
return {
|
1168
|
+
theListContainsNoEntries: "Listen inneholder ingen oppføringer",
|
1169
|
+
copyAll: "Kopier alt",
|
1170
|
+
helpText:
|
1171
|
+
"<p>Du kan kopiere verdier fra enkeltrader<br>" +
|
1172
|
+
"til utklippstavlen ved å dobbeltklikke på den relevante kolonnen.</p>" +
|
1173
|
+
"<p>For å kopiere en hel rad, hold nede Skift-tasten mens du klikker.<br>" +
|
1174
|
+
"Hvis du vil kopiere alle radene, kan du bruke knappen <strong>Kopier alt</strong>.</p>",
|
1175
|
+
};
|
1176
|
+
case "dk":
|
1177
|
+
return {
|
1178
|
+
theListContainsNoEntries: "Listen indeholder ingen poster",
|
1179
|
+
copyAll: "Kopiér alt",
|
1180
|
+
helpText:
|
1181
|
+
"<p>Du kan kopiere værdier fra enkelte rækker<br>" +
|
1182
|
+
"til udklipsholderen ved at dobbeltklikke på den relevante kolonne.</p>" +
|
1183
|
+
"<p>For at kopiere en hel række, hold Shift-tasten nede, mens du klikker.<br>" +
|
1184
|
+
"Hvis du vil kopiere alle rækker, kan du bruge knappen <strong>Kopiér alt</strong>.</p>",
|
1185
|
+
};
|
1186
|
+
case "sw":
|
1187
|
+
return {
|
1188
|
+
theListContainsNoEntries: "Listan innehåller inga poster",
|
1189
|
+
copyAll: "Kopiera allt",
|
1190
|
+
helpText:
|
1191
|
+
"<p>Du kan kopiera värden från enskilda rader<br>" +
|
1192
|
+
"till urklipp genom att dubbelklicka på den relevanta kolumnen.</p>" +
|
1193
|
+
"<p>För att kopiera en hel rad, håll ned Shift-tangenten medan du klickar.<br>" +
|
1194
|
+
"Om du vill kopiera alla rader kan du använda knappen <strong>Kopiera allt</strong>.</p>",
|
1195
|
+
};
|
1196
|
+
|
1197
|
+
case "en":
|
1198
|
+
default:
|
1199
|
+
return {
|
1200
|
+
theListContainsNoEntries: "The list contains no entries",
|
1201
|
+
copyAll: "Copy all",
|
1202
|
+
helpText:
|
1203
|
+
"<p>You can copy the values from individual rows<br>" +
|
1204
|
+
"to the clipboard by double-clicking on the relevant column.</p>" +
|
1205
|
+
"<p>To copy an entire row, hold down the Shift key while clicking.<br>" +
|
1206
|
+
"If you want to copy all rows, you can use the <strong>Copy All</strong> button.</p>",
|
1207
|
+
};
|
1208
|
+
}
|
1224
1209
|
}
|
1225
1210
|
|
1226
1211
|
/**
|
@@ -1228,79 +1213,80 @@ function getTranslations() {
|
|
1228
1213
|
* @return {string}
|
1229
1214
|
*/
|
1230
1215
|
export function getStoredOrderConfigKey() {
|
1231
|
-
|
1216
|
+
return generateUniqueConfigKey("datatable", this?.id, "stored-order");
|
1232
1217
|
}
|
1233
1218
|
|
1234
1219
|
/**
|
1235
1220
|
* @private
|
1236
1221
|
*/
|
1237
1222
|
function storeOrderStatement(doFetch) {
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1223
|
+
const headers = this.getOption("headers");
|
1224
|
+
const delimiter = this.getOption("datasource.orderDelimiter");
|
1225
|
+
const statement = createOrderStatement(headers, delimiter);
|
1226
|
+
setDataSource.call(this, { order: statement }, doFetch);
|
1241
1227
|
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1228
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1229
|
+
if (!(host && this.id)) {
|
1230
|
+
return;
|
1231
|
+
}
|
1246
1232
|
|
1247
|
-
|
1233
|
+
const configKey = getStoredOrderConfigKey.call(this);
|
1248
1234
|
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1235
|
+
// statement explode with , and remove all empty
|
1236
|
+
const list = statement.split(",").filter((item) => item.trim() !== "");
|
1237
|
+
if (list.length === 0) {
|
1238
|
+
return;
|
1239
|
+
}
|
1254
1240
|
|
1255
|
-
|
1241
|
+
host.setConfig(configKey, list);
|
1256
1242
|
}
|
1257
1243
|
|
1258
1244
|
/**
|
1259
1245
|
* @private
|
1260
1246
|
*/
|
1261
1247
|
function updateGrid() {
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1248
|
+
if (!this[gridElementSymbol]) {
|
1249
|
+
throw new Error("no grid element is defined");
|
1250
|
+
}
|
1251
|
+
|
1252
|
+
let gridTemplateColumns = "";
|
1253
|
+
|
1254
|
+
const headers = this.getOption("headers");
|
1255
|
+
|
1256
|
+
let styles = "";
|
1257
|
+
|
1258
|
+
for (let i = 0; i < headers.length; i++) {
|
1259
|
+
const header = headers[i];
|
1260
|
+
|
1261
|
+
if (header.mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
1262
|
+
styles += `[data-monster-role=datatable]>[data-monster-head="${header.labelKey}"] { display: none; }\n`;
|
1263
|
+
styles += `[data-monster-role=datatable-headers]>[data-monster-index="${header.index}"] { display: none; }\n`;
|
1264
|
+
} else {
|
1265
|
+
gridTemplateColumns += `${header.grid} `;
|
1266
|
+
}
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
const sheet = new CSSStyleSheet();
|
1270
|
+
if (styles !== "") sheet.replaceSync(styles);
|
1271
|
+
this.shadowRoot.adoptedStyleSheets = [...DataTable.getCSSStyleSheet(), sheet];
|
1272
|
+
|
1273
|
+
const bodyWidth = this.parentNode.clientWidth;
|
1274
|
+
|
1275
|
+
const breakpoint = this.getOption("responsive.breakpoint");
|
1276
|
+
this[dataControlElementSymbol].classList.toggle(
|
1277
|
+
"small",
|
1278
|
+
bodyWidth <= breakpoint,
|
1279
|
+
);
|
1280
|
+
|
1281
|
+
if (bodyWidth > breakpoint) {
|
1282
|
+
this[gridElementSymbol].style.gridTemplateColumns =
|
1283
|
+
`${gridTemplateColumns}`;
|
1284
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns =
|
1285
|
+
`${gridTemplateColumns}`;
|
1286
|
+
} else {
|
1287
|
+
this[gridElementSymbol].style.gridTemplateColumns = "auto";
|
1288
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns = "auto";
|
1289
|
+
}
|
1304
1290
|
}
|
1305
1291
|
|
1306
1292
|
/**
|
@@ -1308,20 +1294,20 @@ function updateGrid() {
|
|
1308
1294
|
* @param {Header[]} headers
|
1309
1295
|
* @param {bool} doFetch
|
1310
1296
|
*/
|
1311
|
-
function setDataSource({
|
1312
|
-
|
1297
|
+
function setDataSource({ order }, doFetch) {
|
1298
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
1313
1299
|
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1300
|
+
if (!datasource) {
|
1301
|
+
return;
|
1302
|
+
}
|
1317
1303
|
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1304
|
+
if (isFunction(datasource?.setParameters)) {
|
1305
|
+
datasource.setParameters({ order });
|
1306
|
+
}
|
1321
1307
|
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1308
|
+
if (doFetch !== false && isFunction(datasource?.fetch)) {
|
1309
|
+
datasource.fetch();
|
1310
|
+
}
|
1325
1311
|
}
|
1326
1312
|
|
1327
1313
|
/**
|
@@ -1329,30 +1315,30 @@ function setDataSource({orderBy}, doFetch) {
|
|
1329
1315
|
* @return {DataTable}
|
1330
1316
|
*/
|
1331
1317
|
function initControlReferences() {
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1318
|
+
if (!this.shadowRoot) {
|
1319
|
+
throw new Error("no shadow-root is defined");
|
1320
|
+
}
|
1335
1321
|
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1322
|
+
this[dataControlElementSymbol] = this.shadowRoot.querySelector(
|
1323
|
+
"[data-monster-role=control]",
|
1324
|
+
);
|
1339
1325
|
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1326
|
+
this[gridElementSymbol] = this.shadowRoot.querySelector(
|
1327
|
+
"[data-monster-role=datatable]",
|
1328
|
+
);
|
1343
1329
|
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1330
|
+
this[gridHeadersElementSymbol] = this.shadowRoot.querySelector(
|
1331
|
+
"[data-monster-role=datatable-headers]",
|
1332
|
+
);
|
1347
1333
|
|
1348
|
-
|
1349
|
-
|
1334
|
+
this[columnBarElementSymbol] =
|
1335
|
+
this.shadowRoot.querySelector("monster-column-bar");
|
1350
1336
|
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1337
|
+
this[copyAllElementSymbol] = this.shadowRoot.querySelector(
|
1338
|
+
"[data-monster-role=copy-all]",
|
1339
|
+
);
|
1354
1340
|
|
1355
|
-
|
1341
|
+
return this;
|
1356
1342
|
}
|
1357
1343
|
|
1358
1344
|
/**
|
@@ -1362,22 +1348,25 @@ function initControlReferences() {
|
|
1362
1348
|
* @throws {Error} the datasource could not be initialized
|
1363
1349
|
*/
|
1364
1350
|
function initOptionsFromArguments() {
|
1365
|
-
|
1366
|
-
|
1351
|
+
const options = {datasource:{}};
|
1352
|
+
const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
|
1367
1353
|
|
1368
1354
|
if (selector) {
|
1369
1355
|
options.datasource = {selector: selector};
|
1370
1356
|
}
|
1371
1357
|
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1358
|
+
options.datasource.orderDelimiter = "," // workaround for the missing orderDelimiter
|
1359
|
+
|
1360
|
+
const breakpoint = this.getAttribute(
|
1361
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
1362
|
+
);
|
1363
|
+
|
1364
|
+
if (breakpoint) {
|
1365
|
+
options.responsive = {};
|
1366
|
+
options.responsive.breakpoint = parseInt(breakpoint);
|
1367
|
+
}
|
1379
1368
|
|
1380
|
-
|
1369
|
+
return options;
|
1381
1370
|
}
|
1382
1371
|
|
1383
1372
|
/**
|
@@ -1385,7 +1374,7 @@ function initOptionsFromArguments() {
|
|
1385
1374
|
* @return {string}
|
1386
1375
|
*/
|
1387
1376
|
function getEmptyTemplate() {
|
1388
|
-
|
1377
|
+
return `<monster-state data-monster-role="empty-without-action">
|
1389
1378
|
<div part="visual">
|
1390
1379
|
<svg width="4rem" height="4rem" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
1391
1380
|
<path d="m21.5 22h-19c-1.378 0-2.5-1.121-2.5-2.5v-7c0-.07.015-.141.044-.205l3.969-8.82c.404-.896 1.299-1.475 2.28-1.475h11.414c.981 0 1.876.579 2.28 1.475l3.969 8.82c.029.064.044.135.044.205v7c0 1.379-1.122 2.5-2.5 2.5zm-20.5-9.393v6.893c0 .827.673 1.5 1.5 1.5h19c.827 0 1.5-.673 1.5-1.5v-6.893l-3.925-8.723c-.242-.536-.779-.884-1.368-.884h-11.414c-.589 0-1.126.348-1.368.885z"/>
|
@@ -1403,8 +1392,8 @@ function getEmptyTemplate() {
|
|
1403
1392
|
* @return {string}
|
1404
1393
|
*/
|
1405
1394
|
function getTemplate() {
|
1406
|
-
|
1407
|
-
|
1395
|
+
// language=HTML
|
1396
|
+
return `
|
1408
1397
|
<div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
|
1409
1398
|
<template id="headers-row">
|
1410
1399
|
<div data-monster-attributes="class path:headers-row.classes,
|