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