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