@slickgrid-universal/row-detail-view-plugin 2.4.1 → 2.6.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/dist/commonjs/index.js +17 -17
- package/dist/commonjs/slickRowDetailView.js +655 -651
- package/dist/commonjs/slickRowDetailView.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/slickRowDetailView.js +651 -647
- package/dist/esm/slickRowDetailView.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/{commonjs → types}/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{commonjs → types}/slickRowDetailView.d.ts +130 -129
- package/dist/types/slickRowDetailView.d.ts.map +1 -0
- package/package.json +9 -8
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/slickRowDetailView.d.ts +0 -129
|
@@ -1,648 +1,652 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
*
|
|
87
|
-
* @param
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.
|
|
113
|
-
this.
|
|
114
|
-
}
|
|
115
|
-
this._eventHandler.subscribe(this.dataView.
|
|
116
|
-
this._grid.
|
|
117
|
-
this._grid.render();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
var _a
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return this
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.dataView.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
this.
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
this.
|
|
206
|
-
}
|
|
207
|
-
item[`${this._keyPrefix}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
this.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
if (!item[`${this._keyPrefix}
|
|
231
|
-
item[`${this._keyPrefix}
|
|
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
|
-
itemDetail
|
|
273
|
-
|
|
274
|
-
//
|
|
275
|
-
this.
|
|
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
|
-
/** return the
|
|
320
|
-
|
|
321
|
-
return this.
|
|
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
|
-
const
|
|
351
|
-
//
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
this.
|
|
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
|
-
if (this._lastRange.top
|
|
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
|
-
this.
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
this.
|
|
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
|
-
item[
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
dataContext[`${this._keyPrefix}
|
|
510
|
-
dataContext[`${this._keyPrefix}
|
|
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
|
-
html.push(`<div class="
|
|
547
|
-
html.push(`<div class="
|
|
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
|
-
this.
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
1
|
+
import { objectAssignAndExtend } from '@slickgrid-universal/utils';
|
|
2
|
+
/***
|
|
3
|
+
* A plugin to add Row Detail Panel View (for example providing order detail info when clicking on the order row in the grid)
|
|
4
|
+
* Original StackOverflow question & article making this possible (thanks to violet313)
|
|
5
|
+
* https://stackoverflow.com/questions/10535164/can-slickgrids-row-height-be-dynamically-altered#29399927
|
|
6
|
+
* http://violet313.org/slickgrids/#intro
|
|
7
|
+
*/
|
|
8
|
+
export class SlickRowDetailView {
|
|
9
|
+
/** Constructor of the SlickGrid 3rd party plugin, it can optionally receive options */
|
|
10
|
+
constructor(pubSubService) {
|
|
11
|
+
this.pubSubService = pubSubService;
|
|
12
|
+
this._dataViewIdProperty = 'id';
|
|
13
|
+
this._expandableOverride = null;
|
|
14
|
+
this._expandedRows = [];
|
|
15
|
+
this._gridRowBuffer = 0;
|
|
16
|
+
this._gridUid = '';
|
|
17
|
+
this._keyPrefix = '';
|
|
18
|
+
this._lastRange = null;
|
|
19
|
+
this._outsideRange = 5;
|
|
20
|
+
this._rowIdsOutOfViewport = [];
|
|
21
|
+
this._visibleRenderedCellCount = 0;
|
|
22
|
+
this._defaults = {
|
|
23
|
+
alwaysRenderColumn: true,
|
|
24
|
+
columnId: '_detail_selector',
|
|
25
|
+
cssClass: 'detailView-toggle',
|
|
26
|
+
collapseAllOnSort: true,
|
|
27
|
+
collapsedClass: null,
|
|
28
|
+
expandedClass: null,
|
|
29
|
+
keyPrefix: '_',
|
|
30
|
+
loadOnce: false,
|
|
31
|
+
maxRows: null,
|
|
32
|
+
saveDetailViewOnScroll: true,
|
|
33
|
+
singleRowExpand: false,
|
|
34
|
+
useSimpleViewportCalc: false,
|
|
35
|
+
toolTip: '',
|
|
36
|
+
width: 30,
|
|
37
|
+
};
|
|
38
|
+
this.pluginName = 'RowDetailView';
|
|
39
|
+
/** Fired when the async response finished */
|
|
40
|
+
this.onAsyncEndUpdate = new Slick.Event();
|
|
41
|
+
/** This event must be used with the "notify" by the end user once the Asynchronous Server call returns the item detail */
|
|
42
|
+
this.onAsyncResponse = new Slick.Event();
|
|
43
|
+
/** Fired after the row detail gets toggled */
|
|
44
|
+
this.onAfterRowDetailToggle = new Slick.Event();
|
|
45
|
+
/** Fired before the row detail gets toggled */
|
|
46
|
+
this.onBeforeRowDetailToggle = new Slick.Event();
|
|
47
|
+
/** Fired after the row detail gets toggled */
|
|
48
|
+
this.onRowBackToViewportRange = new Slick.Event();
|
|
49
|
+
/** Fired after a row becomes out of viewport range (when user can't see the row anymore) */
|
|
50
|
+
this.onRowOutOfViewportRange = new Slick.Event();
|
|
51
|
+
this._eventHandler = new Slick.EventHandler();
|
|
52
|
+
}
|
|
53
|
+
get addonOptions() {
|
|
54
|
+
return this._addonOptions;
|
|
55
|
+
}
|
|
56
|
+
/** Getter of SlickGrid DataView object */
|
|
57
|
+
get dataView() {
|
|
58
|
+
var _a;
|
|
59
|
+
return ((_a = this._grid) === null || _a === void 0 ? void 0 : _a.getData()) || {};
|
|
60
|
+
}
|
|
61
|
+
get dataViewIdProperty() {
|
|
62
|
+
return this._dataViewIdProperty;
|
|
63
|
+
}
|
|
64
|
+
get eventHandler() {
|
|
65
|
+
return this._eventHandler;
|
|
66
|
+
}
|
|
67
|
+
/** Getter for the Grid Options pulled through the Grid Object */
|
|
68
|
+
get gridOptions() {
|
|
69
|
+
var _a;
|
|
70
|
+
return ((_a = this._grid) === null || _a === void 0 ? void 0 : _a.getOptions()) || {};
|
|
71
|
+
}
|
|
72
|
+
get gridUid() {
|
|
73
|
+
var _a;
|
|
74
|
+
return this._gridUid || (((_a = this._grid) === null || _a === void 0 ? void 0 : _a.getUID()) || '');
|
|
75
|
+
}
|
|
76
|
+
set lastRange(range) {
|
|
77
|
+
this._lastRange = range;
|
|
78
|
+
}
|
|
79
|
+
set rowIdsOutOfViewport(rowIds) {
|
|
80
|
+
this._rowIdsOutOfViewport = rowIds;
|
|
81
|
+
}
|
|
82
|
+
get visibleRenderedCellCount() {
|
|
83
|
+
return this._visibleRenderedCellCount;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Initialize the Export Service
|
|
87
|
+
* @param _grid
|
|
88
|
+
* @param _containerService
|
|
89
|
+
*/
|
|
90
|
+
init(grid) {
|
|
91
|
+
var _a;
|
|
92
|
+
this._grid = grid;
|
|
93
|
+
if (!grid) {
|
|
94
|
+
throw new Error('[Slickgrid-Universal] RowDetailView Plugin requires the Grid instance to be passed as argument to the "init()" method.');
|
|
95
|
+
}
|
|
96
|
+
this._grid = grid;
|
|
97
|
+
this._gridUid = grid.getUID();
|
|
98
|
+
if (!this._addonOptions) {
|
|
99
|
+
this._addonOptions = objectAssignAndExtend(this.gridOptions.rowDetailView, this._defaults);
|
|
100
|
+
}
|
|
101
|
+
this._keyPrefix = ((_a = this._addonOptions) === null || _a === void 0 ? void 0 : _a.keyPrefix) || '_';
|
|
102
|
+
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
|
|
103
|
+
this._gridRowBuffer = this.gridOptions.minRowBuffer || 0;
|
|
104
|
+
this.gridOptions.minRowBuffer = this._addonOptions.panelRows + 3;
|
|
105
|
+
this._eventHandler
|
|
106
|
+
.subscribe(this._grid.onClick, this.handleClick.bind(this))
|
|
107
|
+
.subscribe(this._grid.onBeforeEditCell, () => this.collapseAll())
|
|
108
|
+
.subscribe(this._grid.onScroll, this.handleScroll.bind(this));
|
|
109
|
+
// Sort will, by default, Collapse all of the open items (unless user implements his own onSort which deals with open row and padding)
|
|
110
|
+
if (this._addonOptions.collapseAllOnSort) {
|
|
111
|
+
this._eventHandler.subscribe(this._grid.onSort, this.collapseAll.bind(this));
|
|
112
|
+
this._expandedRows = [];
|
|
113
|
+
this._rowIdsOutOfViewport = [];
|
|
114
|
+
}
|
|
115
|
+
this._eventHandler.subscribe(this.dataView.onRowCountChanged, () => {
|
|
116
|
+
this._grid.updateRowCount();
|
|
117
|
+
this._grid.render();
|
|
118
|
+
});
|
|
119
|
+
this._eventHandler.subscribe(this.dataView.onRowsChanged, (_e, args) => {
|
|
120
|
+
this._grid.invalidateRows(args.rows);
|
|
121
|
+
this._grid.render();
|
|
122
|
+
});
|
|
123
|
+
// subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished
|
|
124
|
+
this._eventHandler.subscribe(this.onAsyncResponse, this.handleOnAsyncResponse.bind(this));
|
|
125
|
+
// after data is set, let's get the DataView Id Property name used (defaults to "id")
|
|
126
|
+
this._eventHandler.subscribe(this.dataView.onSetItemsCalled, () => {
|
|
127
|
+
var _a;
|
|
128
|
+
this._dataViewIdProperty = ((_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getIdPropertyName()) || 'id';
|
|
129
|
+
});
|
|
130
|
+
// if we use the alternative & simpler calculation of the out of viewport range
|
|
131
|
+
// we will need to know how many rows are rendered on the screen and we need to wait for grid to be rendered
|
|
132
|
+
// unfortunately there is no triggered event for knowing when grid is finished, so we use 250ms delay and it's typically more than enough
|
|
133
|
+
if (this._addonOptions.useSimpleViewportCalc) {
|
|
134
|
+
this._eventHandler.subscribe(this._grid.onRendered, (_e, args) => {
|
|
135
|
+
if (args === null || args === void 0 ? void 0 : args.endRow) {
|
|
136
|
+
this._visibleRenderedCellCount = args.endRow - args.startRow;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Dispose of the Slick Row Detail View */
|
|
142
|
+
dispose() {
|
|
143
|
+
var _a;
|
|
144
|
+
(_a = this._eventHandler) === null || _a === void 0 ? void 0 : _a.unsubscribeAll();
|
|
145
|
+
}
|
|
146
|
+
create(columnDefinitions, gridOptions) {
|
|
147
|
+
var _a, _b;
|
|
148
|
+
if (!gridOptions.rowDetailView) {
|
|
149
|
+
throw new Error('[Slickgrid-Universal] The Row Detail View requires options to be passed via the "rowDetailView" property of the Grid Options');
|
|
150
|
+
}
|
|
151
|
+
this._addonOptions = objectAssignAndExtend(gridOptions.rowDetailView, this._defaults);
|
|
152
|
+
// user could override the expandable icon logic from within the options or after instantiating the plugin
|
|
153
|
+
if (typeof this._addonOptions.expandableOverride === 'function') {
|
|
154
|
+
this.expandableOverride(this._addonOptions.expandableOverride);
|
|
155
|
+
}
|
|
156
|
+
if (Array.isArray(columnDefinitions) && gridOptions) {
|
|
157
|
+
const newRowDetailViewColumn = this.getColumnDefinition();
|
|
158
|
+
// add new row detail column unless it was already added
|
|
159
|
+
if (!columnDefinitions.some(col => col.id === newRowDetailViewColumn.id)) {
|
|
160
|
+
const rowDetailColDef = Array.isArray(columnDefinitions) && columnDefinitions.find(col => (col === null || col === void 0 ? void 0 : col.behavior) === 'selectAndMove');
|
|
161
|
+
const finalRowDetailViewColumn = rowDetailColDef ? rowDetailColDef : newRowDetailViewColumn;
|
|
162
|
+
// column index position in the grid
|
|
163
|
+
const columnPosition = (_b = (_a = gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowDetailView) === null || _a === void 0 ? void 0 : _a.columnIndexPosition) !== null && _b !== void 0 ? _b : 0;
|
|
164
|
+
if (columnPosition > 0) {
|
|
165
|
+
columnDefinitions.splice(columnPosition, 0, finalRowDetailViewColumn);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
columnDefinitions.unshift(finalRowDetailViewColumn);
|
|
169
|
+
}
|
|
170
|
+
this.pubSubService.publish(`onPluginColumnsChanged`, {
|
|
171
|
+
columns: columnDefinitions,
|
|
172
|
+
pluginName: this.pluginName
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
/** Get current plugin options */
|
|
179
|
+
getOptions() {
|
|
180
|
+
return this._addonOptions;
|
|
181
|
+
}
|
|
182
|
+
/** set or change some of the plugin options */
|
|
183
|
+
setOptions(options) {
|
|
184
|
+
var _a;
|
|
185
|
+
this._addonOptions = objectAssignAndExtend(options, this._addonOptions);
|
|
186
|
+
if ((_a = this._addonOptions) === null || _a === void 0 ? void 0 : _a.singleRowExpand) {
|
|
187
|
+
this.collapseAll();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Collapse all of the open items */
|
|
191
|
+
collapseAll() {
|
|
192
|
+
this.dataView.beginUpdate();
|
|
193
|
+
for (const expandedRow of this._expandedRows) {
|
|
194
|
+
this.collapseDetailView(expandedRow, true);
|
|
195
|
+
}
|
|
196
|
+
this.dataView.endUpdate();
|
|
197
|
+
}
|
|
198
|
+
/** Colapse an Item so it is not longer seen */
|
|
199
|
+
collapseDetailView(item, isMultipleCollapsing = false) {
|
|
200
|
+
if (!isMultipleCollapsing) {
|
|
201
|
+
this.dataView.beginUpdate();
|
|
202
|
+
}
|
|
203
|
+
// Save the details on the collapse assuming onetime loading
|
|
204
|
+
if (this._addonOptions.loadOnce) {
|
|
205
|
+
this.saveDetailView(item);
|
|
206
|
+
}
|
|
207
|
+
item[`${this._keyPrefix}collapsed`] = true;
|
|
208
|
+
for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {
|
|
209
|
+
this.dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);
|
|
210
|
+
}
|
|
211
|
+
item[`${this._keyPrefix}sizePadding`] = 0;
|
|
212
|
+
this.dataView.updateItem(item[this._dataViewIdProperty], item);
|
|
213
|
+
// Remove the item from the expandedRows
|
|
214
|
+
this._expandedRows = this._expandedRows.filter((expRow) => {
|
|
215
|
+
return expRow[this._dataViewIdProperty] !== item[this._dataViewIdProperty];
|
|
216
|
+
});
|
|
217
|
+
if (!isMultipleCollapsing) {
|
|
218
|
+
this.dataView.endUpdate();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** Expand a row given the dataview item that is to be expanded */
|
|
222
|
+
expandDetailView(item) {
|
|
223
|
+
var _a, _b, _c;
|
|
224
|
+
if ((_a = this._addonOptions) === null || _a === void 0 ? void 0 : _a.singleRowExpand) {
|
|
225
|
+
this.collapseAll();
|
|
226
|
+
}
|
|
227
|
+
item[`${this._keyPrefix}collapsed`] = false;
|
|
228
|
+
this._expandedRows.push(item);
|
|
229
|
+
// In the case something went wrong loading it the first time such a scroll of screen before loaded
|
|
230
|
+
if (!item[`${this._keyPrefix}detailContent`]) {
|
|
231
|
+
item[`${this._keyPrefix}detailViewLoaded`] = false;
|
|
232
|
+
}
|
|
233
|
+
// display pre-loading template
|
|
234
|
+
if (!item[`${this._keyPrefix}detailViewLoaded`] || this._addonOptions.loadOnce !== true) {
|
|
235
|
+
item[`${this._keyPrefix}detailContent`] = (_c = (_b = this._addonOptions) === null || _b === void 0 ? void 0 : _b.preTemplate) === null || _c === void 0 ? void 0 : _c.call(_b, item);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
this.onAsyncResponse.notify({
|
|
239
|
+
item,
|
|
240
|
+
itemDetail: item,
|
|
241
|
+
detailView: item[`${this._keyPrefix}detailContent`]
|
|
242
|
+
});
|
|
243
|
+
this.applyTemplateNewLineHeight(item);
|
|
244
|
+
this.dataView.updateItem(item[this._dataViewIdProperty], item);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
this.applyTemplateNewLineHeight(item);
|
|
248
|
+
this.dataView.updateItem(item[this._dataViewIdProperty], item);
|
|
249
|
+
// async server call
|
|
250
|
+
this._addonOptions.process(item);
|
|
251
|
+
}
|
|
252
|
+
/** Saves the current state of the detail view */
|
|
253
|
+
saveDetailView(item) {
|
|
254
|
+
const view = document.querySelector(`.${this.gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);
|
|
255
|
+
if (view) {
|
|
256
|
+
const html = view.innerHTML;
|
|
257
|
+
if (html !== undefined) {
|
|
258
|
+
item[`${this._keyPrefix}detailContent`] = html;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished
|
|
264
|
+
* the response has to be as "args.item" (or "args.itemDetail") with it's data back
|
|
265
|
+
*/
|
|
266
|
+
handleOnAsyncResponse(_e, args) {
|
|
267
|
+
var _a, _b, _c;
|
|
268
|
+
if (!args || (!args.item && !args.itemDetail)) {
|
|
269
|
+
console.error('SlickRowDetailView plugin requires the onAsyncResponse() to supply "args.item" property.');
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// we accept item/itemDetail, just get the one which has data
|
|
273
|
+
const itemDetail = args.item || args.itemDetail;
|
|
274
|
+
// If we just want to load in a view directly we can use detailView property to do so
|
|
275
|
+
itemDetail[`${this._keyPrefix}detailContent`] = (_a = args.detailView) !== null && _a !== void 0 ? _a : (_c = (_b = this._addonOptions) === null || _b === void 0 ? void 0 : _b.postTemplate) === null || _c === void 0 ? void 0 : _c.call(_b, itemDetail);
|
|
276
|
+
itemDetail[`${this._keyPrefix}detailViewLoaded`] = true;
|
|
277
|
+
this.dataView.updateItem(itemDetail[this._dataViewIdProperty], itemDetail);
|
|
278
|
+
// trigger an event once the post template is finished loading
|
|
279
|
+
this.onAsyncEndUpdate.notify({
|
|
280
|
+
grid: this._grid,
|
|
281
|
+
item: itemDetail,
|
|
282
|
+
itemDetail,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* TODO interface only has a GETTER not a SETTER..why?
|
|
287
|
+
* Override the logic for showing (or not) the expand icon (use case example: only every 2nd row is expandable)
|
|
288
|
+
* Method that user can pass to override the default behavior or making every row an expandable row.
|
|
289
|
+
* In order word, user can choose which rows to be an available row detail (or not) by providing his own logic.
|
|
290
|
+
* @param overrideFn: override function callback
|
|
291
|
+
*/
|
|
292
|
+
expandableOverride(overrideFn) {
|
|
293
|
+
this._expandableOverride = overrideFn;
|
|
294
|
+
}
|
|
295
|
+
getExpandableOverride() {
|
|
296
|
+
return this._expandableOverride;
|
|
297
|
+
}
|
|
298
|
+
/** Get the Column Definition of the first column dedicated to toggling the Row Detail View */
|
|
299
|
+
getColumnDefinition() {
|
|
300
|
+
var _a, _b, _c;
|
|
301
|
+
return {
|
|
302
|
+
id: (_b = (_a = this._addonOptions) === null || _a === void 0 ? void 0 : _a.columnId) !== null && _b !== void 0 ? _b : this._defaults.columnId,
|
|
303
|
+
field: 'sel',
|
|
304
|
+
name: '',
|
|
305
|
+
alwaysRenderColumn: (_c = this._addonOptions) === null || _c === void 0 ? void 0 : _c.alwaysRenderColumn,
|
|
306
|
+
cssClass: this._addonOptions.cssClass || '',
|
|
307
|
+
excludeFromExport: true,
|
|
308
|
+
excludeFromColumnPicker: true,
|
|
309
|
+
excludeFromGridMenu: true,
|
|
310
|
+
excludeFromQuery: true,
|
|
311
|
+
excludeFromHeaderMenu: true,
|
|
312
|
+
formatter: this.detailSelectionFormatter.bind(this),
|
|
313
|
+
resizable: false,
|
|
314
|
+
sortable: false,
|
|
315
|
+
toolTip: this._addonOptions.toolTip,
|
|
316
|
+
width: this._addonOptions.width,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/** return the currently expanded rows */
|
|
320
|
+
getExpandedRows() {
|
|
321
|
+
return this._expandedRows;
|
|
322
|
+
}
|
|
323
|
+
/** return the rows that are out of the viewport */
|
|
324
|
+
getOutOfViewportRows() {
|
|
325
|
+
return this._rowIdsOutOfViewport;
|
|
326
|
+
}
|
|
327
|
+
/** Takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on */
|
|
328
|
+
getFilterItem(item) {
|
|
329
|
+
if (item[`${this._keyPrefix}isPadding`] && item[`${this._keyPrefix}parent`]) {
|
|
330
|
+
item = item[`${this._keyPrefix}parent`];
|
|
331
|
+
}
|
|
332
|
+
return item;
|
|
333
|
+
}
|
|
334
|
+
/** Resize the Row Detail View */
|
|
335
|
+
resizeDetailView(item) {
|
|
336
|
+
if (!item) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
// Grad each of the DOM elements
|
|
340
|
+
const mainContainer = document.querySelector(`.${this.gridUid} .detailViewContainer_${item[this._dataViewIdProperty]}`);
|
|
341
|
+
const cellItem = document.querySelector(`.${this.gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`);
|
|
342
|
+
const inner = document.querySelector(`.${this.gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);
|
|
343
|
+
if (!mainContainer || !cellItem || !inner) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {
|
|
347
|
+
this.dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);
|
|
348
|
+
}
|
|
349
|
+
const rowHeight = this.gridOptions.rowHeight; // height of a row
|
|
350
|
+
const lineHeight = 13; // we know cuz we wrote the custom css init ;)
|
|
351
|
+
// remove the height so we can calculate the height
|
|
352
|
+
mainContainer.style.minHeight = '';
|
|
353
|
+
// Get the scroll height for the main container so we know the actual size of the view
|
|
354
|
+
const itemHeight = mainContainer.scrollHeight;
|
|
355
|
+
// Now work out how many rows
|
|
356
|
+
const rowCount = Math.ceil(itemHeight / rowHeight);
|
|
357
|
+
item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight);
|
|
358
|
+
item[`${this._keyPrefix}height`] = itemHeight;
|
|
359
|
+
let outterHeight = (item[`${this._keyPrefix}sizePadding`] * rowHeight);
|
|
360
|
+
if (this._addonOptions.maxRows !== null && item[`${this._keyPrefix}sizePadding`] > this._addonOptions.maxRows) {
|
|
361
|
+
outterHeight = this._addonOptions.maxRows * rowHeight;
|
|
362
|
+
item[`${this._keyPrefix}sizePadding`] = this._addonOptions.maxRows;
|
|
363
|
+
}
|
|
364
|
+
// If the padding is now more than the original minRowBuff we need to increase it
|
|
365
|
+
if (this.gridOptions.minRowBuffer < item[`${this._keyPrefix}sizePadding`]) {
|
|
366
|
+
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
|
|
367
|
+
this.gridOptions.minRowBuffer = item[`${this._keyPrefix}sizePadding`] + 3;
|
|
368
|
+
}
|
|
369
|
+
mainContainer.setAttribute('style', `min-height: ${item[this._keyPrefix + 'height']}px`);
|
|
370
|
+
if (cellItem) {
|
|
371
|
+
cellItem.setAttribute('style', `height: ${outterHeight}px; top: ${rowHeight}px`);
|
|
372
|
+
}
|
|
373
|
+
const idxParent = this.dataView.getIdxById(item[this._dataViewIdProperty]);
|
|
374
|
+
for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {
|
|
375
|
+
this.dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
|
|
376
|
+
}
|
|
377
|
+
// Lastly save the updated state
|
|
378
|
+
this.saveDetailView(item);
|
|
379
|
+
}
|
|
380
|
+
// --
|
|
381
|
+
// protected functions
|
|
382
|
+
// ------------------
|
|
383
|
+
/**
|
|
384
|
+
* create the detail ctr node. this belongs to the dev & can be custom-styled as per
|
|
385
|
+
*/
|
|
386
|
+
applyTemplateNewLineHeight(item) {
|
|
387
|
+
// the height is calculated by the template row count (how many line of items does the template view have)
|
|
388
|
+
const rowCount = this._addonOptions.panelRows;
|
|
389
|
+
// calculate padding requirements based on detail-content..
|
|
390
|
+
// ie. worst-case: create an invisible dom node now & find it's height.
|
|
391
|
+
const lineHeight = 13; // we know cuz we wrote the custom css init ;)
|
|
392
|
+
item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / this.gridOptions.rowHeight);
|
|
393
|
+
item[`${this._keyPrefix}height`] = (item[`${this._keyPrefix}sizePadding`] * this.gridOptions.rowHeight);
|
|
394
|
+
const idxParent = this.dataView.getIdxById(item[this._dataViewIdProperty]);
|
|
395
|
+
for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {
|
|
396
|
+
this.dataView.insertItem((idxParent || 0) + idx, this.getPaddingItem(item, idx));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
calculateOutOfRangeViews() {
|
|
400
|
+
if (this._grid) {
|
|
401
|
+
let scrollDir;
|
|
402
|
+
const renderedRange = this._grid.getRenderedRange();
|
|
403
|
+
// Only check if we have expanded rows
|
|
404
|
+
if (this._expandedRows.length > 0) {
|
|
405
|
+
// Assume scroll direction is down by default.
|
|
406
|
+
scrollDir = 'DOWN';
|
|
407
|
+
if (this._lastRange) {
|
|
408
|
+
// Some scrolling isn't anything as the range is the same
|
|
409
|
+
if (this._lastRange.top === renderedRange.top && this._lastRange.bottom === renderedRange.bottom) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// If our new top is smaller we are scrolling up
|
|
413
|
+
if (this._lastRange.top > renderedRange.top ||
|
|
414
|
+
// Or we are at very top but our bottom is increasing
|
|
415
|
+
(this._lastRange.top === 0 && renderedRange.top === 0 && (this._lastRange.bottom > renderedRange.bottom))) {
|
|
416
|
+
scrollDir = 'UP';
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
this._expandedRows.forEach((row) => {
|
|
421
|
+
const rowIndex = this.dataView.getRowById(row[this._dataViewIdProperty]);
|
|
422
|
+
const rowPadding = row[`${this._keyPrefix}sizePadding`];
|
|
423
|
+
const isRowOutOfRange = this._rowIdsOutOfViewport.some(rowId => rowId === row[this._dataViewIdProperty]);
|
|
424
|
+
if (scrollDir === 'UP') {
|
|
425
|
+
// save the view when asked
|
|
426
|
+
if (this._addonOptions.saveDetailViewOnScroll) {
|
|
427
|
+
// If the bottom item within buffer range is an expanded row save it.
|
|
428
|
+
if (rowIndex >= renderedRange.bottom - this._gridRowBuffer) {
|
|
429
|
+
this.saveDetailView(row);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// If the row expanded area is within the buffer notify that it is back in range
|
|
433
|
+
if (isRowOutOfRange && ((rowIndex - this._outsideRange) < renderedRange.top) && (rowIndex >= renderedRange.top)) {
|
|
434
|
+
this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);
|
|
435
|
+
}
|
|
436
|
+
else if (!isRowOutOfRange && ((rowIndex + rowPadding) > renderedRange.bottom)) {
|
|
437
|
+
// if our first expanded row is about to go off the bottom
|
|
438
|
+
this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else if (scrollDir === 'DOWN') {
|
|
442
|
+
// save the view when asked
|
|
443
|
+
if (this._addonOptions.saveDetailViewOnScroll) {
|
|
444
|
+
// If the top item within buffer range is an expanded row save it.
|
|
445
|
+
if (rowIndex <= renderedRange.top + this._gridRowBuffer) {
|
|
446
|
+
this.saveDetailView(row);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// If row index is i higher than bottom with some added value (To ignore top rows off view) and is with view and was our of range
|
|
450
|
+
if (isRowOutOfRange && ((rowIndex + rowPadding + this._outsideRange) > renderedRange.bottom) && (rowIndex < (rowIndex + rowPadding))) {
|
|
451
|
+
this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);
|
|
452
|
+
}
|
|
453
|
+
else if (!isRowOutOfRange && (rowIndex < renderedRange.top)) {
|
|
454
|
+
// if our row is outside top of and the buffering zone but not in the array of outOfVisable range notify it
|
|
455
|
+
this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
this._lastRange = renderedRange;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
calculateOutOfRangeViewsSimplerVersion() {
|
|
463
|
+
if (this._grid) {
|
|
464
|
+
const renderedRange = this._grid.getRenderedRange();
|
|
465
|
+
this._expandedRows.forEach((row) => {
|
|
466
|
+
const rowIndex = this.dataView.getRowById(row[this._dataViewIdProperty]);
|
|
467
|
+
const isOutOfVisibility = this.checkIsRowOutOfViewportRange(rowIndex, renderedRange);
|
|
468
|
+
if (!isOutOfVisibility && this._rowIdsOutOfViewport.some(rowId => rowId === row[this._dataViewIdProperty])) {
|
|
469
|
+
this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);
|
|
470
|
+
}
|
|
471
|
+
else if (isOutOfVisibility) {
|
|
472
|
+
this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
checkExpandableOverride(row, dataContext, grid) {
|
|
478
|
+
if (typeof this._expandableOverride === 'function') {
|
|
479
|
+
return this._expandableOverride(row, dataContext, grid);
|
|
480
|
+
}
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
checkIsRowOutOfViewportRange(rowIndex, renderedRange) {
|
|
484
|
+
return (Math.abs(renderedRange.bottom - this._gridRowBuffer - rowIndex) > this._visibleRenderedCellCount * 2);
|
|
485
|
+
}
|
|
486
|
+
/** Get the Row Detail padding (which are the rows dedicated to the detail panel) */
|
|
487
|
+
getPaddingItem(parent, offset) {
|
|
488
|
+
const item = {};
|
|
489
|
+
for (const prop in this.dataView) {
|
|
490
|
+
if (prop) {
|
|
491
|
+
item[prop] = null;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
item[this._dataViewIdProperty] = `${parent[this._dataViewIdProperty]}.${offset}`;
|
|
495
|
+
// additional hidden padding metadata fields
|
|
496
|
+
item[`${this._keyPrefix}collapsed`] = true;
|
|
497
|
+
item[`${this._keyPrefix}isPadding`] = true;
|
|
498
|
+
item[`${this._keyPrefix}parent`] = parent;
|
|
499
|
+
item[`${this._keyPrefix}offset`] = offset;
|
|
500
|
+
return item;
|
|
501
|
+
}
|
|
502
|
+
/** The Formatter of the toggling icon of the Row Detail */
|
|
503
|
+
detailSelectionFormatter(row, cell, value, columnDef, dataContext, grid) {
|
|
504
|
+
if (!this.checkExpandableOverride(row, dataContext, grid)) {
|
|
505
|
+
return '';
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
if (dataContext[`${this._keyPrefix}collapsed`] === undefined) {
|
|
509
|
+
dataContext[`${this._keyPrefix}collapsed`] = true;
|
|
510
|
+
dataContext[`${this._keyPrefix}sizePadding`] = 0; // the required number of pading rows
|
|
511
|
+
dataContext[`${this._keyPrefix}height`] = 0; // the actual height in pixels of the detail field
|
|
512
|
+
dataContext[`${this._keyPrefix}isPadding`] = false;
|
|
513
|
+
dataContext[`${this._keyPrefix}parent`] = undefined;
|
|
514
|
+
dataContext[`${this._keyPrefix}offset`] = 0;
|
|
515
|
+
}
|
|
516
|
+
if (dataContext[`${this._keyPrefix}isPadding`]) {
|
|
517
|
+
// render nothing
|
|
518
|
+
}
|
|
519
|
+
else if (dataContext[`${this._keyPrefix}collapsed`]) {
|
|
520
|
+
let collapsedClasses = `${this._addonOptions.cssClass || ''} expand `;
|
|
521
|
+
if (this._addonOptions.collapsedClass) {
|
|
522
|
+
collapsedClasses += this._addonOptions.collapsedClass;
|
|
523
|
+
}
|
|
524
|
+
return `<div class="${collapsedClasses.trim()}"></div>`;
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
const html = [];
|
|
528
|
+
const rowHeight = this.gridOptions.rowHeight || 0;
|
|
529
|
+
let outterHeight = (dataContext[`${this._keyPrefix}sizePadding`] || 0) * this.gridOptions.rowHeight;
|
|
530
|
+
if (this._addonOptions.maxRows !== null && ((dataContext[`${this._keyPrefix}sizePadding`] || 0) > this._addonOptions.maxRows)) {
|
|
531
|
+
outterHeight = this._addonOptions.maxRows * rowHeight;
|
|
532
|
+
dataContext[`${this._keyPrefix}sizePadding`] = this._addonOptions.maxRows;
|
|
533
|
+
}
|
|
534
|
+
// V313HAX:
|
|
535
|
+
// putting in an extra closing div after the closing toggle div and ommiting a
|
|
536
|
+
// final closing div for the detail ctr div causes the slickgrid renderer to
|
|
537
|
+
// insert our detail div as a new column ;) ~since it wraps whatever we provide
|
|
538
|
+
// in a generic div column container. so our detail becomes a child directly of
|
|
539
|
+
// the row not the cell. nice =) ~no need to apply a css change to the parent
|
|
540
|
+
// slick-cell to escape the cell overflow clipping.
|
|
541
|
+
// sneaky extra </div> inserted here-----------------v
|
|
542
|
+
let expandedClasses = `${this._addonOptions.cssClass || ''} collapse `;
|
|
543
|
+
if (this._addonOptions.expandedClass) {
|
|
544
|
+
expandedClasses += this._addonOptions.expandedClass;
|
|
545
|
+
}
|
|
546
|
+
html.push(`<div class="${expandedClasses.trim()}"></div></div>`);
|
|
547
|
+
html.push(`<div class="dynamic-cell-detail cellDetailView_${dataContext[this._dataViewIdProperty]}" `); // apply custom css to detail
|
|
548
|
+
html.push(`style="height: ${outterHeight}px;`); // set total height of padding
|
|
549
|
+
html.push(`top: ${rowHeight}px">`); // shift detail below 1st row
|
|
550
|
+
html.push(`<div class="detail-container detailViewContainer_${dataContext[this._dataViewIdProperty]}">`); // sub ctr for custom styling
|
|
551
|
+
html.push(`<div class="innerDetailView_${dataContext[this._dataViewIdProperty]}">${dataContext[`${this._keyPrefix}detailContent`]}</div></div>`);
|
|
552
|
+
// omit a final closing detail container </div> that would come next
|
|
553
|
+
return html.join('');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return '';
|
|
557
|
+
}
|
|
558
|
+
/** When row is getting toggled, we will handle the action of collapsing/expanding */
|
|
559
|
+
handleAccordionShowHide(item) {
|
|
560
|
+
if (item) {
|
|
561
|
+
if (!item[`${this._keyPrefix}collapsed`]) {
|
|
562
|
+
this.collapseDetailView(item);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
this.expandDetailView(item);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/** Handle mouse click event */
|
|
570
|
+
handleClick(e, args) {
|
|
571
|
+
const dataContext = this._grid.getDataItem(args.row);
|
|
572
|
+
if (this.checkExpandableOverride(args.row, dataContext, this._grid)) {
|
|
573
|
+
// clicking on a row select checkbox
|
|
574
|
+
const columnDef = this._grid.getColumns()[args.cell];
|
|
575
|
+
if (this._addonOptions.useRowClick || (columnDef.id === this._addonOptions.columnId && e.target.classList.contains(this._addonOptions.cssClass || ''))) {
|
|
576
|
+
// if editing, try to commit
|
|
577
|
+
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
|
|
578
|
+
e.preventDefault();
|
|
579
|
+
e.stopImmediatePropagation();
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
// trigger an event before toggling
|
|
583
|
+
this.onBeforeRowDetailToggle.notify({
|
|
584
|
+
grid: this._grid,
|
|
585
|
+
item: dataContext
|
|
586
|
+
});
|
|
587
|
+
this.toggleRowSelection(args.row, dataContext);
|
|
588
|
+
// trigger an event after toggling
|
|
589
|
+
this.onAfterRowDetailToggle.notify({
|
|
590
|
+
grid: this._grid,
|
|
591
|
+
item: dataContext,
|
|
592
|
+
expandedRows: this._expandedRows,
|
|
593
|
+
});
|
|
594
|
+
e.stopPropagation();
|
|
595
|
+
e.stopImmediatePropagation();
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
handleScroll() {
|
|
600
|
+
if (this._addonOptions.useSimpleViewportCalc) {
|
|
601
|
+
this.calculateOutOfRangeViewsSimplerVersion();
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
this.calculateOutOfRangeViews();
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
notifyOutOfViewport(item, rowId) {
|
|
608
|
+
const rowIndex = item.rowIndex || this.dataView.getRowById(item[this._dataViewIdProperty]);
|
|
609
|
+
this.onRowOutOfViewportRange.notify({
|
|
610
|
+
grid: this._grid,
|
|
611
|
+
item,
|
|
612
|
+
rowId,
|
|
613
|
+
rowIndex,
|
|
614
|
+
expandedRows: this._expandedRows,
|
|
615
|
+
rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, true)
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
notifyBackToViewportWhenDomExist(item, rowId) {
|
|
619
|
+
const rowIndex = item.rowIndex || this.dataView.getRowById(item[this._dataViewIdProperty]);
|
|
620
|
+
setTimeout(() => {
|
|
621
|
+
// make sure View Row DOM Element really exist before notifying that it's a row that is visible again
|
|
622
|
+
if (document.querySelector(`.${this.gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`)) {
|
|
623
|
+
this.onRowBackToViewportRange.notify({
|
|
624
|
+
grid: this._grid,
|
|
625
|
+
item,
|
|
626
|
+
rowId,
|
|
627
|
+
rowIndex,
|
|
628
|
+
expandedRows: this._expandedRows,
|
|
629
|
+
rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, false)
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}, 100);
|
|
633
|
+
}
|
|
634
|
+
syncOutOfViewportArray(rowId, isAdding) {
|
|
635
|
+
const arrayRowIndex = this._rowIdsOutOfViewport.findIndex(outOfViewportRowId => outOfViewportRowId === rowId);
|
|
636
|
+
if (isAdding && arrayRowIndex < 0) {
|
|
637
|
+
this._rowIdsOutOfViewport.push(rowId);
|
|
638
|
+
}
|
|
639
|
+
else if (!isAdding && arrayRowIndex >= 0) {
|
|
640
|
+
this._rowIdsOutOfViewport.splice(arrayRowIndex, 1);
|
|
641
|
+
}
|
|
642
|
+
return this._rowIdsOutOfViewport;
|
|
643
|
+
}
|
|
644
|
+
toggleRowSelection(rowNumber, dataContext) {
|
|
645
|
+
if (this.checkExpandableOverride(rowNumber, dataContext, this._grid)) {
|
|
646
|
+
this.dataView.beginUpdate();
|
|
647
|
+
this.handleAccordionShowHide(dataContext);
|
|
648
|
+
this.dataView.endUpdate();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
648
652
|
//# sourceMappingURL=slickRowDetailView.js.map
|