@cntwg/html-helper 0.0.15 → 0.0.16
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/lib/html-ctrls-list.js +150 -81
- package/package.json +1 -1
package/lib/html-ctrls-list.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
// [v0.1.
|
|
1
|
+
// [v0.1.051-20221009]
|
|
2
2
|
|
|
3
3
|
// === module init block ===
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
-
readAsBool,
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
//readAsBool,
|
|
7
|
+
readAsNumber,
|
|
8
|
+
//valueToIndex,
|
|
9
|
+
//isArray, isObject,
|
|
9
10
|
isPlainObject,
|
|
10
11
|
TItemsListEx,
|
|
11
12
|
} = require('@ygracs/bsfoc-lib-js');
|
|
@@ -28,6 +29,10 @@ const {
|
|
|
28
29
|
CSS_CLASS_ACTIVE,
|
|
29
30
|
} = CSS_CLASS_STRING;
|
|
30
31
|
|
|
32
|
+
const ILC_SMODE_DEF = 0;
|
|
33
|
+
const ILC_SMODE_SHFT = 1;
|
|
34
|
+
const ILC_SMODE_CTRL = 2;
|
|
35
|
+
|
|
31
36
|
// === module extra block (helper functions) ===
|
|
32
37
|
|
|
33
38
|
function readAsAttrValue(value){
|
|
@@ -229,14 +234,16 @@ class THtmlItemsListContainer {
|
|
|
229
234
|
|
|
230
235
|
delItem(index, opt){
|
|
231
236
|
const forceCI = typeof opt === 'boolean' ? opt : true;
|
|
232
|
-
const
|
|
237
|
+
const _items = this.#_items;
|
|
238
|
+
const item = _items.delItemEx(index, forceCI);
|
|
233
239
|
const isSUCCEED = isHTMLElement(item);
|
|
234
240
|
if (isSUCCEED) {
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
241
|
+
const index = _items.curIndex;
|
|
242
|
+
if (index === -1) {
|
|
243
|
+
this.rstCurIndex();
|
|
244
|
+
} else {
|
|
245
|
+
this.setCurIndex(_items.curIndex);
|
|
246
|
+
};
|
|
240
247
|
if (this.#_host) item.remove();
|
|
241
248
|
};
|
|
242
249
|
return isSUCCEED;
|
|
@@ -313,6 +320,9 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
313
320
|
isStubItemShown: false,
|
|
314
321
|
isHostEnabled: isHostEnabled,
|
|
315
322
|
catchEventOnHost: false,
|
|
323
|
+
execDelItem: false,
|
|
324
|
+
execDelItemDI: -1,
|
|
325
|
+
execDelItemCI: -1,
|
|
316
326
|
}
|
|
317
327
|
// bind ref to host
|
|
318
328
|
this.#_host = _host;
|
|
@@ -334,23 +344,31 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
334
344
|
|
|
335
345
|
#_on_will_select_item = (e) => {
|
|
336
346
|
//console.log('THtmlItemsListController._on_will_select_item() ==> was called...');
|
|
337
|
-
//console.log('CHECK: e => ditail:['+e.detail+']');
|
|
338
|
-
//console.log('CHECK: e => phase:['+e.eventPhase+']');
|
|
339
347
|
//e.preventDefault(); /* need to reconsider reason for use */
|
|
348
|
+
const {
|
|
349
|
+
eventPhase,
|
|
350
|
+
target,
|
|
351
|
+
currentTarget,
|
|
352
|
+
ctrlKey,
|
|
353
|
+
shiftKey,
|
|
354
|
+
} = e;
|
|
355
|
+
//console.log('CHECK: e => ditail:['+e.detail+']');
|
|
356
|
+
//console.log('CHECK: e => phase:['+eventPhase+']');
|
|
357
|
+
const onClickNum = readAsNumber(e.detail, 0);
|
|
340
358
|
const _status = this.#_status;
|
|
341
359
|
const { isSelectionLocked, catchEventOnHost } = _status;
|
|
342
|
-
const on_click_num = readAsNumber(e.detail, 0);
|
|
343
360
|
let curItem = null;
|
|
344
|
-
switch (
|
|
345
|
-
//*case 1:
|
|
361
|
+
switch (eventPhase) {
|
|
346
362
|
//* // NOTE: currently on eventPhase = 2 and 3
|
|
347
|
-
case
|
|
363
|
+
//*case 1:
|
|
348
364
|
/**/// capturing stage
|
|
349
|
-
|
|
365
|
+
case 2:
|
|
366
|
+
/**/// target stage
|
|
367
|
+
if (target !== this.#_host) curItem = target;
|
|
350
368
|
break;
|
|
351
369
|
case 3:
|
|
352
370
|
/**/// bubblig stage
|
|
353
|
-
curItem = catchEventOnHost ?
|
|
371
|
+
curItem = catchEventOnHost ? target : currentTarget;
|
|
354
372
|
break;
|
|
355
373
|
default:
|
|
356
374
|
break;
|
|
@@ -358,61 +376,15 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
358
376
|
if (
|
|
359
377
|
!isSelectionLocked
|
|
360
378
|
&& curItem instanceof HTMLElement
|
|
361
|
-
&& (
|
|
379
|
+
&& (onClickNum === 0 || onClickNum === 1)
|
|
362
380
|
&& !curItem.classList.contains(CSS_CLASS_DISABLED)
|
|
363
381
|
) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> current:['+c_index+']');
|
|
371
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> next:['+n_index+']');
|
|
372
|
-
let act_in_mode = 0;
|
|
373
|
-
let act_unsel_grp = false;
|
|
374
|
-
if (this.#_options.allowGroupSelection) {
|
|
375
|
-
if (c_index !== -1) {
|
|
376
|
-
if (key_ctrl) {
|
|
377
|
-
act_in_mode = 2;
|
|
378
|
-
} else if (key_shft) {
|
|
379
|
-
act_in_mode = 1;
|
|
380
|
-
} else if (this.#_selects.size > 0) {
|
|
381
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> _selects.size:['+this.#_selects.size+']');
|
|
382
|
-
act_unsel_grp = true;
|
|
383
|
-
};
|
|
384
|
-
};
|
|
385
|
-
};
|
|
386
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> mode:['+act_in_mode+']');
|
|
387
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> act_unsel_grp:['+act_unsel_grp+']');
|
|
388
|
-
if (act_unsel_grp) {
|
|
389
|
-
for (let item of this.#_selects) {
|
|
390
|
-
c_index = this.srchIndex(item);
|
|
391
|
-
if (c_index !== -1) this.unselectItem(c_index);
|
|
392
|
-
};
|
|
393
|
-
c_index = -1;
|
|
394
|
-
};
|
|
395
|
-
if (act_in_mode === 1) {
|
|
396
|
-
if (c_index > n_index) [ c_index, n_index ] = [ n_index, c_index ];
|
|
397
|
-
let t_index = 0;
|
|
398
|
-
for (let item of this.#_selects) {
|
|
399
|
-
t_index = this.srchIndex(item);
|
|
400
|
-
if (t_index !== -1) this.unselectItem(t_index);
|
|
401
|
-
};
|
|
402
|
-
this.#_selects.clear();
|
|
403
|
-
for (let i = c_index; i < n_index + 1; i++) {
|
|
404
|
-
this.selectItem(i, false);
|
|
405
|
-
};
|
|
406
|
-
} else if (act_in_mode === 2) {
|
|
407
|
-
if (this.isSelectedItem(n_index)) {
|
|
408
|
-
this.unselectItem(n_index);
|
|
409
|
-
} else {
|
|
410
|
-
this.selectItem(n_index, false);
|
|
411
|
-
};
|
|
412
|
-
} else if (c_index !== n_index) {
|
|
413
|
-
if (c_index !== -1) this.unselectItem(c_index);
|
|
414
|
-
this.selectItem(n_index, true);
|
|
415
|
-
};
|
|
382
|
+
//console.log('CHECK: e => tag:['+curItem.tagName+']');
|
|
383
|
+
this.#_selectItemEx(curItem, {
|
|
384
|
+
ctrlKey: ctrlKey,
|
|
385
|
+
shiftKey: shiftKey,
|
|
386
|
+
forceCI: true,
|
|
387
|
+
});
|
|
416
388
|
};
|
|
417
389
|
};
|
|
418
390
|
|
|
@@ -463,19 +435,39 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
463
435
|
this.#_status.isSelectionLocked = false;
|
|
464
436
|
}
|
|
465
437
|
|
|
466
|
-
|
|
438
|
+
#_setCurIndex(index){
|
|
467
439
|
const isSUCCEED = super.setCurIndex(index);
|
|
468
440
|
if (isSUCCEED) this.#_triggerEvent('current-item-chosen', {
|
|
469
441
|
index: Number(index),
|
|
470
442
|
item: null,
|
|
471
443
|
});
|
|
472
444
|
return isSUCCEED;
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
setCurIndex(index){
|
|
448
|
+
return this.selectItem(index, true);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
rstCurIndex(){
|
|
452
|
+
const {
|
|
453
|
+
execDelItem,
|
|
454
|
+
execDelItemDI,
|
|
455
|
+
execDelItemCI,
|
|
456
|
+
} = this.#_status;
|
|
457
|
+
if (execDelItem) {
|
|
458
|
+
let index = execDelItemCI;
|
|
459
|
+
if (execDelItemCI !== -1) index--;
|
|
460
|
+
if (index !== -1 && execDelItemDI !== execDelItemCI) {
|
|
461
|
+
this.unselectItem(index);
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
super.rstCurIndex();
|
|
473
465
|
}
|
|
474
466
|
|
|
475
467
|
addItem(item, opt){
|
|
476
468
|
const index = super.addItem(item, false);
|
|
477
469
|
if (index !== -1) {
|
|
478
|
-
const { autoHideNewItems, showStubsIfEmpty }
|
|
470
|
+
const { autoHideNewItems, showStubsIfEmpty } = this.#_options;
|
|
479
471
|
const _status = this.#_status;
|
|
480
472
|
const { catchEventOnHost, isStubItemShown } = _status;
|
|
481
473
|
if (!catchEventOnHost) {
|
|
@@ -504,29 +496,45 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
504
496
|
item: item,
|
|
505
497
|
});
|
|
506
498
|
};
|
|
507
|
-
if (forceCI)
|
|
499
|
+
if (forceCI) {
|
|
500
|
+
this.#_selectItemEx(item, {
|
|
501
|
+
ctrlKey: false,
|
|
502
|
+
shiftKey: false,
|
|
503
|
+
forceCI: forceCI,
|
|
504
|
+
});
|
|
505
|
+
};
|
|
508
506
|
};
|
|
509
507
|
return index;
|
|
510
508
|
}
|
|
511
509
|
|
|
512
510
|
delItem(index, opt){
|
|
513
|
-
|
|
514
|
-
|
|
511
|
+
const item = super.getItem(index);
|
|
512
|
+
const _status = this.#_status;
|
|
513
|
+
let isSUCCEED = isHTMLElement(item);
|
|
514
|
+
if (isSUCCEED) {
|
|
515
|
+
_status.execDelItem = true;
|
|
516
|
+
_status.execDelItemCI = this.curIndex;
|
|
517
|
+
_status.execDelItemDI = Number(index);
|
|
518
|
+
isSUCCEED = super.delItem(index, opt);
|
|
519
|
+
_status.execDelItemDI = -1;
|
|
520
|
+
_status.execDelItemCI = -1;
|
|
521
|
+
_status.execDelItem = false;
|
|
522
|
+
};
|
|
515
523
|
if (isSUCCEED) {
|
|
516
524
|
const _options = this.#_options;
|
|
517
|
-
const _status = this.#_status;
|
|
518
525
|
if (!_status.catchEventOnHost) {
|
|
519
526
|
// remove event handler on element if it was set by addItem()
|
|
520
527
|
item.removeEventListener('click', this.#_on_will_select_item);
|
|
521
528
|
};
|
|
522
|
-
this.#_selects.delete(item);
|
|
523
529
|
if (this.isEmpty()) {
|
|
530
|
+
this.#_selects.clear();
|
|
524
531
|
if (_options.showStubsIfEmpty) {
|
|
525
532
|
// show default stub-item
|
|
526
533
|
_status.isStubItemShown = this.#_stubs.showDefItem();
|
|
527
534
|
};
|
|
528
535
|
this.#_triggerEvent('list-clear');
|
|
529
536
|
} else {
|
|
537
|
+
this.#_selects.delete(item);
|
|
530
538
|
this.#_triggerEvent('item-removed', {
|
|
531
539
|
index: Number(index),
|
|
532
540
|
item: item,
|
|
@@ -536,17 +544,78 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
536
544
|
return isSUCCEED;
|
|
537
545
|
}
|
|
538
546
|
|
|
539
|
-
|
|
547
|
+
#_selectItem(index){
|
|
540
548
|
const item = super.getItem(index);
|
|
541
|
-
|
|
549
|
+
const isSUCCEED = selectHtmlElement(item);
|
|
542
550
|
if (isSUCCEED) {
|
|
543
551
|
this.#_selects.add(item);
|
|
544
552
|
this.#_triggerEvent('item-selected', {
|
|
545
553
|
index: Number(index),
|
|
546
554
|
item: item,
|
|
547
555
|
});
|
|
556
|
+
};
|
|
557
|
+
return isSUCCEED;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
#_selectItemEx(item, opt){
|
|
561
|
+
const _selects = this.#_selects;
|
|
562
|
+
let {
|
|
563
|
+
ctrlKey = false,
|
|
564
|
+
shiftKey = false,
|
|
565
|
+
forceCI = false,
|
|
566
|
+
} = opt;
|
|
567
|
+
let mode = ILC_SMODE_DEF;
|
|
568
|
+
let doUnSelGrp = false;
|
|
569
|
+
let indexCI = this.curIndex;
|
|
570
|
+
let indexNI = this.srchIndex(item);
|
|
571
|
+
if (indexCI !== -1) {
|
|
572
|
+
if (this.#_options.allowGroupSelection) {
|
|
573
|
+
if (shiftKey) {
|
|
574
|
+
mode = ILC_SMODE_SHFT;
|
|
575
|
+
if (_selects.size > 0) doUnSelGrp = true;
|
|
576
|
+
} else if (ctrlKey) {
|
|
577
|
+
mode = ILC_SMODE_CTRL;
|
|
578
|
+
} else if (_selects.size > 0) {
|
|
579
|
+
doUnSelGrp = true;
|
|
580
|
+
};
|
|
581
|
+
} else if (_selects.size > 0) {
|
|
582
|
+
doUnSelGrp = true;
|
|
583
|
+
};
|
|
584
|
+
};
|
|
585
|
+
if (doUnSelGrp) {
|
|
586
|
+
for (let item of _selects) {
|
|
587
|
+
this.unselectItem(this.srchIndex(item));
|
|
588
|
+
};
|
|
589
|
+
_selects.clear();
|
|
590
|
+
};
|
|
591
|
+
switch (mode) {
|
|
592
|
+
case ILC_SMODE_SHFT:
|
|
593
|
+
if (indexCI > indexNI) [ indexCI, indexNI ] = [ indexNI, indexCI ];
|
|
594
|
+
for (let i = indexCI; i < indexNI + 1; i++) {
|
|
595
|
+
this.#_selectItem(i);
|
|
596
|
+
};
|
|
597
|
+
break;
|
|
598
|
+
case ILC_SMODE_CTRL:
|
|
599
|
+
this.#_selectItem(this.srchIndex(item));
|
|
600
|
+
break;
|
|
601
|
+
default:
|
|
602
|
+
if (this.#_selectItem(this.srchIndex(item))) {
|
|
603
|
+
if (forceCI) this.#_setCurIndex(indexNI);
|
|
604
|
+
};
|
|
605
|
+
break;
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
selectItem(index, opt){
|
|
610
|
+
const item = super.getItem(index);
|
|
611
|
+
let isSUCCEED = isHTMLElement(item);
|
|
612
|
+
if (isSUCCEED) {
|
|
548
613
|
const forceCI = typeof opt === 'boolean' ? opt : false;
|
|
549
|
-
|
|
614
|
+
this.#_selectItemEx(item, {
|
|
615
|
+
ctrlKey: false,
|
|
616
|
+
shiftKey: false,
|
|
617
|
+
forceCI: forceCI,
|
|
618
|
+
});
|
|
550
619
|
};
|
|
551
620
|
return isSUCCEED;
|
|
552
621
|
}
|