@liedekef/ftable 1.1.49 → 1.1.50

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.
Files changed (38) hide show
  1. package/ftable.esm.js +233 -87
  2. package/ftable.js +233 -87
  3. package/ftable.min.js +2 -24
  4. package/ftable.umd.js +233 -87
  5. package/package.json +1 -1
  6. package/themes/basic/ftable_basic.css +15 -8
  7. package/themes/basic/ftable_basic.min.css +1 -1
  8. package/themes/ftable_theme_base.less +17 -11
  9. package/themes/lightcolor/blue/ftable.css +15 -8
  10. package/themes/lightcolor/blue/ftable.min.css +1 -1
  11. package/themes/lightcolor/gray/ftable.css +15 -8
  12. package/themes/lightcolor/gray/ftable.min.css +1 -1
  13. package/themes/lightcolor/green/ftable.css +15 -8
  14. package/themes/lightcolor/green/ftable.min.css +1 -1
  15. package/themes/lightcolor/orange/ftable.css +15 -8
  16. package/themes/lightcolor/orange/ftable.min.css +1 -1
  17. package/themes/lightcolor/red/ftable.css +15 -8
  18. package/themes/lightcolor/red/ftable.min.css +1 -1
  19. package/themes/metro/blue/ftable.css +15 -8
  20. package/themes/metro/blue/ftable.min.css +1 -1
  21. package/themes/metro/brown/ftable.css +15 -8
  22. package/themes/metro/brown/ftable.min.css +1 -1
  23. package/themes/metro/crimson/ftable.css +15 -8
  24. package/themes/metro/crimson/ftable.min.css +1 -1
  25. package/themes/metro/darkgray/ftable.css +15 -8
  26. package/themes/metro/darkgray/ftable.min.css +1 -1
  27. package/themes/metro/darkorange/ftable.css +15 -8
  28. package/themes/metro/darkorange/ftable.min.css +1 -1
  29. package/themes/metro/green/ftable.css +15 -8
  30. package/themes/metro/green/ftable.min.css +1 -1
  31. package/themes/metro/lightgray/ftable.css +15 -8
  32. package/themes/metro/lightgray/ftable.min.css +1 -1
  33. package/themes/metro/pink/ftable.css +15 -8
  34. package/themes/metro/pink/ftable.min.css +1 -1
  35. package/themes/metro/purple/ftable.css +15 -8
  36. package/themes/metro/purple/ftable.min.css +1 -1
  37. package/themes/metro/red/ftable.css +15 -8
  38. package/themes/metro/red/ftable.min.css +1 -1
package/ftable.umd.js CHANGED
@@ -1453,12 +1453,9 @@ class FTableFormBuilder {
1453
1453
  parent: display
1454
1454
  });
1455
1455
 
1456
- // Create options dropdown
1457
- const dropdown = FTableDOMHelper.create('div', {
1458
- className: 'ftable-multiselect-dropdown',
1459
- parent: container,
1460
- style: 'display: none;'
1461
- });
1456
+ // Dropdown and overlay will be created on demand and appended to body
1457
+ let dropdown = null;
1458
+ let dropdownOverlay = null;
1462
1459
 
1463
1460
  // Store selected values and checkbox references
1464
1461
  const selectedValues = new Set(
@@ -1526,9 +1523,53 @@ class FTableFormBuilder {
1526
1523
  hiddenInput.value = Array.from(selectedValues).join(',');
1527
1524
  };
1528
1525
 
1526
+ // Function to close dropdown
1527
+ const closeDropdown = () => {
1528
+ if (dropdown) {
1529
+ dropdown.remove();
1530
+ dropdown = null;
1531
+ }
1532
+ if (dropdownOverlay) {
1533
+ dropdownOverlay.remove();
1534
+ dropdownOverlay = null;
1535
+ }
1536
+ if (container._cleanupHandlers) {
1537
+ container._cleanupHandlers();
1538
+ container._cleanupHandlers = null;
1539
+ }
1540
+ };
1541
+
1542
+ // Function to position dropdown
1543
+ const positionDropdown = () => {
1544
+ if (!dropdown) return;
1545
+
1546
+ const rect = display.getBoundingClientRect();
1547
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
1548
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
1549
+
1550
+ let left = rect.left + scrollLeft;
1551
+ let top = rect.bottom + scrollTop + 4; // 4px gap
1552
+
1553
+ dropdown.style.position = 'absolute';
1554
+ dropdown.style.left = `${left}px`;
1555
+ dropdown.style.top = `${top}px`;
1556
+ dropdown.style.width = `${rect.width}px`;
1557
+ dropdown.style.minWidth = `${rect.width}px`;
1558
+ dropdown.style.boxSizing = 'border-box';
1559
+ dropdown.style.zIndex = '10000';
1560
+
1561
+ // Adjust horizontal position if needed
1562
+ const dropdownRect = dropdown.getBoundingClientRect();
1563
+ const viewportWidth = window.innerWidth;
1564
+ if (dropdownRect.right > viewportWidth) {
1565
+ left = Math.max(10, viewportWidth - dropdownRect.width - 10);
1566
+ dropdown.style.left = `${left}px`;
1567
+ }
1568
+ };
1569
+
1529
1570
  // Populate options
1530
1571
  const populateOptions = () => {
1531
- if (!field.options) return;
1572
+ if (!field.options || !dropdown) return;
1532
1573
 
1533
1574
  const options = Array.isArray(field.options) ? field.options :
1534
1575
  Object.entries(field.options).map(([k, v]) => ({Value: k, DisplayText: v}));
@@ -1585,26 +1626,74 @@ class FTableFormBuilder {
1585
1626
  // Toggle dropdown
1586
1627
  const toggleDropdown = (e) => {
1587
1628
  if (e) e.stopPropagation();
1588
- const isVisible = dropdown.style.display !== 'none';
1589
- dropdown.style.display = isVisible ? 'none' : 'block';
1590
1629
 
1591
- if (!isVisible) {
1592
- // Close other dropdowns
1593
- document.querySelectorAll('.ftable-multiselect-dropdown').forEach(dd => {
1594
- if (dd !== dropdown) dd.style.display = 'none';
1630
+ if (dropdown) {
1631
+ // Dropdown is open, close it
1632
+ closeDropdown();
1633
+ } else {
1634
+ // Close any other open multiselect dropdowns
1635
+ document.querySelectorAll('.ftable-multiselect-dropdown').forEach(dd => dd.remove());
1636
+ document.querySelectorAll('.ftable-multiselect-overlay').forEach(ov => ov.remove());
1637
+
1638
+ // Create overlay
1639
+ dropdownOverlay = FTableDOMHelper.create('div', {
1640
+ className: 'ftable-multiselect-overlay',
1641
+ parent: document.body
1642
+ });
1643
+
1644
+ // Create dropdown
1645
+ dropdown = FTableDOMHelper.create('div', {
1646
+ className: 'ftable-multiselect-dropdown',
1647
+ parent: document.body
1595
1648
  });
1649
+
1650
+ // Populate options
1651
+ populateOptions();
1652
+
1653
+ // Position dropdown
1654
+ positionDropdown();
1655
+
1656
+ // Handle clicks outside
1657
+ dropdownOverlay.addEventListener('click', (event) => {
1658
+ if (event.target === dropdownOverlay) {
1659
+ closeDropdown();
1660
+ }
1661
+ });
1662
+
1663
+ // Reposition on scroll/resize
1664
+ const repositionHandler = () => positionDropdown();
1665
+ window.addEventListener('scroll', repositionHandler, true);
1666
+ window.addEventListener('resize', repositionHandler);
1667
+
1668
+ // Store cleanup function
1669
+ container._cleanupHandlers = () => {
1670
+ window.removeEventListener('scroll', repositionHandler, true);
1671
+ window.removeEventListener('resize', repositionHandler);
1672
+ };
1596
1673
  }
1597
1674
  };
1598
1675
 
1599
1676
  display.addEventListener('click', toggleDropdown);
1600
1677
  toggleBtn.addEventListener('click', toggleDropdown);
1601
1678
 
1602
- // Close dropdown when clicking outside
1603
- document.addEventListener('click', (e) => {
1604
- if (!container.contains(e.target)) {
1605
- dropdown.style.display = 'none';
1606
- }
1679
+ // Clean up when container is removed from DOM
1680
+ const observer = new MutationObserver((mutations) => {
1681
+ mutations.forEach((mutation) => {
1682
+ mutation.removedNodes.forEach((node) => {
1683
+ if (node === container || node.contains && node.contains(container)) {
1684
+ closeDropdown();
1685
+ observer.disconnect();
1686
+ }
1687
+ });
1688
+ });
1607
1689
  });
1690
+
1691
+ // Start observing once container is in the DOM
1692
+ setTimeout(() => {
1693
+ if (container.parentNode) {
1694
+ observer.observe(container.parentNode, { childList: true, subtree: true });
1695
+ }
1696
+ }, 0);
1608
1697
 
1609
1698
  // Initialize
1610
1699
  populateOptions();
@@ -1932,9 +2021,6 @@ class FTable extends FTableEventEmitter {
1932
2021
  this.updateSortingHeaders();
1933
2022
  this.renderSortingInfo();
1934
2023
 
1935
- // Add essential CSS if not already present
1936
- //this.addEssentialCSS();
1937
-
1938
2024
  // now make sure all tables have a % width
1939
2025
  this.initColumnWidths();
1940
2026
  }
@@ -2014,40 +2100,6 @@ class FTable extends FTableEventEmitter {
2014
2100
  return result;
2015
2101
  }
2016
2102
 
2017
- addEssentialCSS() {
2018
- // Check if our CSS is already added
2019
- if (document.querySelector('#ftable-essential-css')) return;
2020
-
2021
- const css = `
2022
- .ftable-row-animation {
2023
- transition: background-color 0.3s ease;
2024
- }
2025
-
2026
- .ftable-row-added {
2027
- background-color: #d4edda !important;
2028
- }
2029
-
2030
- .ftable-row-edited {
2031
- background-color: #d1ecf1 !important;
2032
- }
2033
-
2034
- .ftable-row-deleted {
2035
- opacity: 0;
2036
- transform: translateY(-10px);
2037
- transition: opacity 0.3s ease, transform 0.3s ease;
2038
- }
2039
-
2040
- .ftable-toolbarsearch {
2041
- width: 90%;
2042
- }
2043
- `;
2044
-
2045
- const style = document.createElement('style');
2046
- style.id = 'ftable-essential-css';
2047
- style.textContent = css;
2048
- document.head.appendChild(style);
2049
- }
2050
-
2051
2103
  createPagingUI() {
2052
2104
  this.elements.bottomPanel = FTableDOMHelper.create('div', {
2053
2105
  className: 'ftable-bottom-panel',
@@ -2704,12 +2756,9 @@ class FTable extends FTableEventEmitter {
2704
2756
  parent: display
2705
2757
  });
2706
2758
 
2707
- // Create options dropdown
2708
- const dropdown = FTableDOMHelper.create('div', {
2709
- className: 'ftable-multiselect-dropdown',
2710
- parent: container,
2711
- style: 'display: none;'
2712
- });
2759
+ // Dropdown and overlay will be created on demand and appended to body
2760
+ let dropdown = null;
2761
+ let dropdownOverlay = null;
2713
2762
 
2714
2763
  // Store selected values and checkbox references
2715
2764
  const selectedValues = new Set();
@@ -2776,18 +2825,53 @@ class FTable extends FTableEventEmitter {
2776
2825
  }
2777
2826
  };
2778
2827
 
2779
- // Add reset method to container
2780
- container.resetMultiSelect = () => {
2781
- selectedValues.clear();
2782
- checkboxMap.forEach(checkbox => {
2783
- checkbox.checked = false;
2784
- });
2785
- updateDisplay();
2828
+ // Function to close dropdown
2829
+ const closeDropdown = () => {
2830
+ if (dropdown) {
2831
+ dropdown.remove();
2832
+ dropdown = null;
2833
+ }
2834
+ if (dropdownOverlay) {
2835
+ dropdownOverlay.remove();
2836
+ dropdownOverlay = null;
2837
+ }
2838
+ if (container._cleanupHandlers) {
2839
+ container._cleanupHandlers();
2840
+ container._cleanupHandlers = null;
2841
+ }
2842
+ };
2843
+
2844
+ // Function to position dropdown
2845
+ const positionDropdown = () => {
2846
+ if (!dropdown) return;
2847
+
2848
+ const rect = display.getBoundingClientRect();
2849
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
2850
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
2851
+
2852
+ let left = rect.left + scrollLeft;
2853
+ let top = rect.bottom + scrollTop + 4; // 4px gap
2854
+
2855
+ dropdown.style.position = 'absolute';
2856
+ dropdown.style.left = `${left}px`;
2857
+ dropdown.style.top = `${top}px`;
2858
+ dropdown.style.width = `${rect.width}px`;
2859
+ dropdown.style.minWidth = `${rect.width}px`;
2860
+ dropdown.style.boxSizing = 'border-box';
2861
+ dropdown.style.zIndex = '10000';
2862
+
2863
+ // Adjust horizontal position if needed
2864
+ const dropdownRect = dropdown.getBoundingClientRect();
2865
+ const viewportWidth = window.innerWidth;
2866
+ if (dropdownRect.right > viewportWidth) {
2867
+ left = Math.max(10, viewportWidth - dropdownRect.width - 10);
2868
+ dropdown.style.left = `${left}px`;
2869
+ }
2786
2870
  };
2787
2871
 
2788
2872
  // Populate options in both hidden select and dropdown
2789
2873
  const populateOptions = () => {
2790
- if (!optionsSource) return;
2874
+ if (!optionsSource || !dropdown) return;
2791
2875
 
2792
2876
  const options = Array.isArray(optionsSource) ? optionsSource :
2793
2877
  Object.entries(optionsSource).map(([k, v]) => ({Value: k, DisplayText: v}));
@@ -2803,12 +2887,14 @@ class FTable extends FTableEventEmitter {
2803
2887
 
2804
2888
  const optText = option.DisplayText || option.text || option;
2805
2889
 
2806
- // Add to hidden select
2807
- FTableDOMHelper.create('option', {
2808
- value: optValue,
2809
- textContent: optText,
2810
- parent: hiddenSelect
2811
- });
2890
+ // Add to hidden select (only once)
2891
+ if (!hiddenSelect.querySelector(`option[value="${optValue}"]`)) {
2892
+ FTableDOMHelper.create('option', {
2893
+ value: optValue,
2894
+ textContent: optText,
2895
+ parent: hiddenSelect
2896
+ });
2897
+ }
2812
2898
 
2813
2899
  // Add to visual dropdown
2814
2900
  const optionDiv = FTableDOMHelper.create('div', {
@@ -2822,6 +2908,9 @@ class FTable extends FTableEventEmitter {
2822
2908
  parent: optionDiv
2823
2909
  });
2824
2910
 
2911
+ // Set initial checked state
2912
+ checkbox.checked = selectedValues.has(optValue.toString());
2913
+
2825
2914
  // Store checkbox reference
2826
2915
  checkboxMap.set(optValue.toString(), checkbox);
2827
2916
 
@@ -2851,29 +2940,86 @@ class FTable extends FTableEventEmitter {
2851
2940
  // Toggle dropdown
2852
2941
  const toggleDropdown = (e) => {
2853
2942
  if (e) e.stopPropagation();
2854
- const isVisible = dropdown.style.display !== 'none';
2855
- dropdown.style.display = isVisible ? 'none' : 'block';
2856
2943
 
2857
- if (!isVisible) {
2858
- // Close other dropdowns
2859
- document.querySelectorAll('.ftable-multiselect-dropdown').forEach(dd => {
2860
- if (dd !== dropdown) dd.style.display = 'none';
2944
+ if (dropdown) {
2945
+ // Dropdown is open, close it
2946
+ closeDropdown();
2947
+ } else {
2948
+ // Close any other open multiselect dropdowns
2949
+ document.querySelectorAll('.ftable-multiselect-dropdown').forEach(dd => dd.remove());
2950
+ document.querySelectorAll('.ftable-multiselect-overlay').forEach(ov => ov.remove());
2951
+
2952
+ // Create overlay
2953
+ dropdownOverlay = FTableDOMHelper.create('div', {
2954
+ className: 'ftable-multiselect-overlay',
2955
+ parent: document.body
2861
2956
  });
2957
+
2958
+ // Create dropdown
2959
+ dropdown = FTableDOMHelper.create('div', {
2960
+ className: 'ftable-multiselect-dropdown',
2961
+ parent: document.body
2962
+ });
2963
+
2964
+ // Populate options
2965
+ populateOptions();
2966
+
2967
+ // Position dropdown
2968
+ positionDropdown();
2969
+
2970
+ // Handle clicks outside
2971
+ dropdownOverlay.addEventListener('click', (event) => {
2972
+ if (event.target === dropdownOverlay) {
2973
+ closeDropdown();
2974
+ }
2975
+ });
2976
+
2977
+ // Reposition on scroll/resize
2978
+ const repositionHandler = () => positionDropdown();
2979
+ window.addEventListener('scroll', repositionHandler, true);
2980
+ window.addEventListener('resize', repositionHandler);
2981
+
2982
+ // Store cleanup function
2983
+ container._cleanupHandlers = () => {
2984
+ window.removeEventListener('scroll', repositionHandler, true);
2985
+ window.removeEventListener('resize', repositionHandler);
2986
+ };
2862
2987
  }
2863
2988
  };
2864
2989
 
2865
2990
  display.addEventListener('click', toggleDropdown);
2866
2991
  toggleBtn.addEventListener('click', toggleDropdown);
2867
2992
 
2868
- // Close dropdown when clicking outside
2869
- document.addEventListener('click', (e) => {
2870
- if (!container.contains(e.target)) {
2871
- dropdown.style.display = 'none';
2872
- }
2993
+ // Add reset method to container
2994
+ container.resetMultiSelect = () => {
2995
+ selectedValues.clear();
2996
+ checkboxMap.forEach(checkbox => {
2997
+ checkbox.checked = false;
2998
+ });
2999
+ closeDropdown();
3000
+ updateDisplay();
3001
+ };
3002
+
3003
+ // Clean up when container is removed from DOM
3004
+ const observer = new MutationObserver((mutations) => {
3005
+ mutations.forEach((mutation) => {
3006
+ mutation.removedNodes.forEach((node) => {
3007
+ if (node === container || node.contains && node.contains(container)) {
3008
+ closeDropdown();
3009
+ observer.disconnect();
3010
+ }
3011
+ });
3012
+ });
2873
3013
  });
3014
+
3015
+ // Start observing once container is in the DOM
3016
+ setTimeout(() => {
3017
+ if (container.parentNode) {
3018
+ observer.observe(container.parentNode, { childList: true, subtree: true });
3019
+ }
3020
+ }, 0);
2874
3021
 
2875
3022
  // Initialize
2876
- populateOptions();
2877
3023
  updateDisplay();
2878
3024
 
2879
3025
  return container;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liedekef/ftable",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Modern, lightweight, jQuery-free CRUD table for dynamic AJAX-powered tables.",
5
5
  "main": "ftable.js",
6
6
  "module": "ftable.esm.js",
@@ -425,6 +425,17 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
425
425
  position: relative;
426
426
  display: inline-block;
427
427
  width: 100%;
428
+ min-width: 200px;
429
+ }
430
+ /* Overlay for closing dropdown when clicking outside */
431
+ .ftable-multiselect-overlay {
432
+ position: fixed;
433
+ top: 0;
434
+ left: 0;
435
+ right: 0;
436
+ bottom: 0;
437
+ background: transparent;
438
+ z-index: 9999;
428
439
  }
429
440
  .ftable-multiselect-display {
430
441
  display: flex;
@@ -440,10 +451,6 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
440
451
  .ftable-multiselect-display:hover {
441
452
  border-color: #999;
442
453
  }
443
- .ftable-multiselect-display:focus-within {
444
- border-color: #4CAF50;
445
- box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
446
- }
447
454
  .ftable-multiselect-selected {
448
455
  display: flex;
449
456
  flex-wrap: wrap;
@@ -453,7 +460,6 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
453
460
  }
454
461
  .ftable-multiselect-placeholder {
455
462
  color: #555;
456
- font-weight: normal;
457
463
  }
458
464
  .ftable-multiselect-tag {
459
465
  display: inline-flex;
@@ -504,13 +510,14 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
504
510
  color: #333;
505
511
  }
506
512
  .ftable-multiselect-dropdown {
507
- position: relative;
513
+ /* Position is set dynamically via JavaScript */
508
514
  background: white;
509
515
  border: 1px solid #ccc;
510
516
  border-radius: 4px;
511
517
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
512
518
  max-height: 200px;
513
519
  overflow-y: auto;
520
+ z-index: 10000;
514
521
  }
515
522
  .ftable-multiselect-option {
516
523
  display: flex;
@@ -518,7 +525,7 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
518
525
  padding: 4px 8px;
519
526
  cursor: pointer;
520
527
  user-select: none;
521
- gap: 8px;
528
+ gap: 4px;
522
529
  }
523
530
  .ftable-multiselect-option:hover {
524
531
  background: #f5f5f5;
@@ -535,7 +542,7 @@ div.ftable-column-selection-container ul.ftable-column-select-list li input[type
535
542
  }
536
543
  /* For search toolbar version */
537
544
  .ftable-multiselect-search .ftable-multiselect-display {
538
- min-height: 20px;
545
+ min-height: 22px;
539
546
  }
540
547
  /* Responsive adjustments */
541
548
  @media (max-width: 768px) {
@@ -1 +1 @@
1
- div.ftable-main-container{position:relative}div.ftable-main-container div.ftable-title{position:relative;text-align:left}div.ftable-main-container div.ftable-title div.ftable-toolbar{bottom:0;right:0;position:absolute;display:inline-block;margin-right:5px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item{position:relative;display:inline-block;margin:0 0 0 5px;cursor:pointer;font-size:.9em;padding:2px;border:none}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon{display:inline-block;margin:2px;vertical-align:middle;width:16px;height:16px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon.ftable-toolbar-item-add-record{display:inline-flex;align-items:center;background-color:transparent;justify-content:center;width:16px;height:16px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon.ftable-toolbar-item-add-record::before{content:"➕";font-size:14px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-text{display:inline-block;margin:2px;vertical-align:middle}div.ftable-main-container table.ftable{width:100%}div.ftable-main-container table.ftable thead th{padding:0 3px 0 6px;vertical-align:middle;text-align:left}div.ftable-main-container table.ftable thead th.ftable-column-header{height:1px}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container{position:relative;display:table;width:100%;height:100%!important}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container span.ftable-column-header-text{display:table-cell;vertical-align:middle;padding-top:4px;padding-bottom:3px}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container div.ftable-column-resize-handler{position:absolute;display:table-cell;vertical-align:middle;height:100%;width:8px;right:-8px;z-index:2;cursor:col-resize}div.ftable-main-container table.ftable thead th.ftable-command-column-header{text-align:center;width:1%}div.ftable-main-container table.ftable thead th.ftable-column-header-select{text-align:center;width:1%}div.ftable-main-container table.ftable thead th.ftable-column-header-select input{cursor:pointer}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable{cursor:pointer}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-sortable-text{padding-right:20px}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container{position:relative}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::after,div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::before{content:'';position:absolute;top:50%;transform:translateY(-50%);font-size:1.1em;color:#999;opacity:.7;text-shadow:0 1px 0 rgba(255,255,255,.5)}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::before{content:'▲';right:.55em}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::after{content:'▼';right:0}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-asc .ftable-column-header-container::before{color:#222;opacity:1;font-weight:700}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-asc .ftable-column-header-container::after{opacity:.7}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-desc .ftable-column-header-container::after{color:#222;opacity:1;font-weight:700}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-desc .ftable-column-header-container::before{opacity:.7}div.ftable-main-container table.ftable tbody tr>td .ftable-command-button{margin:5px;padding:0;cursor:pointer;border:none;display:inline}div.ftable-main-container table.ftable tbody tr>td .ftable-command-button span{display:none}div.ftable-main-container table.ftable tbody tr>td.ftable-command-column{text-align:center;vertical-align:middle}div.ftable-main-container table.ftable tbody tr>td.ftable-selecting-column{text-align:center;vertical-align:middle}div.ftable-main-container table.ftable tbody tr>td.ftable-selecting-column input{cursor:pointer}div.ftable-main-container table.ftable tbody tr>td .ftable-edit-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-edit-command-button::before{content:"📝";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr>td .ftable-clone-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-clone-command-button::before{content:"📋";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr>td .ftable-delete-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-delete-command-button::before{content:"🗑️ ";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr.ftable-no-data-row{text-align:center}div.ftable-main-container>div.ftable-bottom-panel{position:relative;min-height:24px;text-align:left}div.ftable-main-container>div.ftable-bottom-panel div.ftable-right-area{right:0;top:0;bottom:0;position:absolute}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list{display:inline-block}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-active,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-first,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-last,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-next,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-previous,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-space{padding:2px 5px;display:inline-block;cursor:pointer}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-active,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-disabled,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-space{cursor:default}div.ftable-main-container>div.ftable-bottom-panel span.ftable-page-size-change{margin-left:5px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-goto-page{margin-left:5px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-goto-page input[type=text]{width:22px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-page-info{vertical-align:middle}div.ftable-main-container div.ftable-column-resize-bar{opacity:.5;position:absolute;width:1px;background-color:#000}form.ftable-dialog-form div.ftable-input-field-container{padding:2px 0 3px 0;border-bottom:1px solid #ddd}form.ftable-dialog-form div.ftable-input-field-container:last-child{border:none}form.ftable-dialog-form div.ftable-input-label{padding:2px 3px;font-size:1.1em;color:#666}form.ftable-dialog-form div.ftable-input{padding:2px}form.ftable-dialog-form span.ftable-option-text-clickable{position:relative;top:-2px}form.ftable-dialog-form div.ftable-textarea-input textarea{width:300px;min-height:60px}form.ftable-dialog-form div.ftable-checkbox-input span,form.ftable-dialog-form div.ftable-radio-input span{padding-left:4px}form.ftable-dialog-form div.ftable-checkbox-input input,form.ftable-dialog-form div.ftable-radio-input input,form.ftable-dialog-form span.ftable-option-text-clickable{cursor:pointer}.ftable-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5);z-index:1000;display:none}.ftable-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#fff;padding:20px;border-radius:5px;box-shadow:0 2px 10px rgba(0,0,0,.3);z-index:1001;max-width:90%;max-height:90vh;overflow:auto}.ftable-modal-header{margin-bottom:15px;margin-top:0;padding-bottom:10px;border-bottom:1px solid #eee}.ftable-modal-footer{margin-top:15px;padding-top:10px;border-top:1px solid #eee;text-align:right}.ftable-modal-close{position:absolute;top:10px;right:10px;cursor:pointer;font-size:28px;font-weight:700;color:#aaa}.ftable-busy-modal{padding:0}.ftable-dialog-button{opacity:.8;border:1px solid #ccc;padding:5px;margin:5px}.ftable-dialog-button:hover{background-color:#dedede}div.ftable-busy-message{cursor:wait;margin:0}div.ftable-contextmenu-overlay{position:fixed;left:0;top:0;width:100%;height:100%;z-index:100}.ftable-table-div{display:block;overflow-x:auto}.ftable-table-div>table{overflow:hidden}.ftable-toolbarsearch{width:90%;min-width:fit-content}th.ftable-toolbarsearch-reset{text-align:center!important}div.ftable-column-selection-container{position:absolute;border:1px solid #c8c8c8;background:#fff;color:#000;z-index:101;padding:5px}div.ftable-column-selection-container ul.ftable-column-select-list{margin:0;padding:0;list-style:none}div.ftable-column-selection-container ul.ftable-column-select-list li{margin:0;padding:2px 0}div.ftable-column-selection-container ul.ftable-column-select-list li label span{position:relative;top:-1px;margin-left:4px}div.ftable-column-selection-container ul.ftable-column-select-list li input[type=checkbox]{cursor:pointer}.ftable-yesno-check-wrapper{display:flex;align-items:center}.ftable-yesno-check-fixedlabel,.ftable-yesno-check-text{margin-left:4px}.ftable-yesno-check-text:before{content:attr(data-no)}.ftable-yesno-check-input:checked~.ftable-yesno-check-text:before{content:attr(data-yes)}.ftable-multiselect-container{position:relative;display:inline-block;width:100%}.ftable-multiselect-display{display:flex;align-items:center;background:#fff;border:1px solid #ccc;border-radius:4px;cursor:pointer;min-height:38px;padding:4px 30px 4px 8px;position:relative}.ftable-multiselect-display:hover{border-color:#999}.ftable-multiselect-display:focus-within{border-color:#4caf50;box-shadow:0 0 0 2px rgba(76,175,80,.2)}.ftable-multiselect-selected{display:flex;flex-wrap:wrap;gap:4px;flex:1;align-items:center}.ftable-multiselect-placeholder{color:#555;font-weight:400}.ftable-multiselect-tag{display:inline-flex;align-items:center;background:#e3f2fd;border:1px solid #90caf9;border-radius:3px;padding:2px 6px;font-size:13px;gap:6px;max-width:100%}.ftable-multiselect-tag-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ftable-multiselect-tag-remove{cursor:pointer;font-weight:700;color:#1976d2;font-size:18px;line-height:1;padding:0 2px;user-select:none}.ftable-multiselect-tag-remove:hover{color:#d32f2f}.ftable-multiselect-count{color:#666;font-size:12px;margin-left:4px;white-space:nowrap}.ftable-multiselect-toggle{position:absolute;right:0;background:0 0;border:none;cursor:pointer;padding:4px;color:#666;font-size:10px;line-height:1}.ftable-multiselect-toggle:hover{color:#333}.ftable-multiselect-dropdown{position:relative;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 4px 6px rgba(0,0,0,.1);max-height:200px;overflow-y:auto}.ftable-multiselect-option{display:flex;align-items:center;padding:4px 8px;cursor:pointer;user-select:none;gap:8px}.ftable-multiselect-option:hover{background:#f5f5f5}.ftable-multiselect-checkbox{cursor:pointer;margin:0;flex-shrink:0}.ftable-multiselect-label{cursor:pointer;flex:1;margin:0}.ftable-multiselect-search .ftable-multiselect-display{min-height:20px}@media (max-width:768px){.ftable-multiselect-dropdown{max-height:200px}.ftable-multiselect-tag{font-size:12px}}.ftable-multiselect-dropdown::-webkit-scrollbar{width:8px}.ftable-multiselect-dropdown::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.ftable-multiselect-dropdown::-webkit-scrollbar-thumb{background:#888;border-radius:4px}.ftable-multiselect-dropdown::-webkit-scrollbar-thumb:hover{background:#555}div.ftable-main-container div.ftable-title div.ftable-title-text{font-size:16px;font-weight:700}div.ftable-busy-message{color:#000;background-color:#ddd;font-size:1.25em}
1
+ div.ftable-main-container{position:relative}div.ftable-main-container div.ftable-title{position:relative;text-align:left}div.ftable-main-container div.ftable-title div.ftable-toolbar{bottom:0;right:0;position:absolute;display:inline-block;margin-right:5px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item{position:relative;display:inline-block;margin:0 0 0 5px;cursor:pointer;font-size:.9em;padding:2px;border:none}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon{display:inline-block;margin:2px;vertical-align:middle;width:16px;height:16px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon.ftable-toolbar-item-add-record{display:inline-flex;align-items:center;background-color:transparent;justify-content:center;width:16px;height:16px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-icon.ftable-toolbar-item-add-record::before{content:"➕";font-size:14px}div.ftable-main-container div.ftable-title div.ftable-toolbar .ftable-toolbar-item span.ftable-toolbar-item-text{display:inline-block;margin:2px;vertical-align:middle}div.ftable-main-container table.ftable{width:100%}div.ftable-main-container table.ftable thead th{padding:0 3px 0 6px;vertical-align:middle;text-align:left}div.ftable-main-container table.ftable thead th.ftable-column-header{height:1px}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container{position:relative;display:table;width:100%;height:100%!important}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container span.ftable-column-header-text{display:table-cell;vertical-align:middle;padding-top:4px;padding-bottom:3px}div.ftable-main-container table.ftable thead th.ftable-column-header div.ftable-column-header-container div.ftable-column-resize-handler{position:absolute;display:table-cell;vertical-align:middle;height:100%;width:8px;right:-8px;z-index:2;cursor:col-resize}div.ftable-main-container table.ftable thead th.ftable-command-column-header{text-align:center;width:1%}div.ftable-main-container table.ftable thead th.ftable-column-header-select{text-align:center;width:1%}div.ftable-main-container table.ftable thead th.ftable-column-header-select input{cursor:pointer}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable{cursor:pointer}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-sortable-text{padding-right:20px}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container{position:relative}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::after,div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::before{content:'';position:absolute;top:50%;transform:translateY(-50%);font-size:1.1em;color:#999;opacity:.7;text-shadow:0 1px 0 rgba(255,255,255,.5)}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::before{content:'▲';right:.55em}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable .ftable-column-header-container::after{content:'▼';right:0}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-asc .ftable-column-header-container::before{color:#222;opacity:1;font-weight:700}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-asc .ftable-column-header-container::after{opacity:.7}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-desc .ftable-column-header-container::after{color:#222;opacity:1;font-weight:700}div.ftable-main-container table.ftable thead th.ftable-column-header-sortable.ftable-column-header-sorted-desc .ftable-column-header-container::before{opacity:.7}div.ftable-main-container table.ftable tbody tr>td .ftable-command-button{margin:5px;padding:0;cursor:pointer;border:none;display:inline}div.ftable-main-container table.ftable tbody tr>td .ftable-command-button span{display:none}div.ftable-main-container table.ftable tbody tr>td.ftable-command-column{text-align:center;vertical-align:middle}div.ftable-main-container table.ftable tbody tr>td.ftable-selecting-column{text-align:center;vertical-align:middle}div.ftable-main-container table.ftable tbody tr>td.ftable-selecting-column input{cursor:pointer}div.ftable-main-container table.ftable tbody tr>td .ftable-edit-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-edit-command-button::before{content:"📝";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr>td .ftable-clone-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-clone-command-button::before{content:"📋";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr>td .ftable-delete-command-button{width:16px;height:16px;background-color:transparent}div.ftable-main-container table.ftable tbody tr>td .ftable-delete-command-button::before{content:"🗑️ ";font-size:14px;display:flex;align-items:center;justify-content:center;width:100%;height:100%}div.ftable-main-container table.ftable tbody tr.ftable-no-data-row{text-align:center}div.ftable-main-container>div.ftable-bottom-panel{position:relative;min-height:24px;text-align:left}div.ftable-main-container>div.ftable-bottom-panel div.ftable-right-area{right:0;top:0;bottom:0;position:absolute}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list{display:inline-block}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-active,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-first,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-last,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-next,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-previous,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-space{padding:2px 5px;display:inline-block;cursor:pointer}div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-active,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-disabled,div.ftable-main-container>div.ftable-bottom-panel .ftable-page-list .ftable-page-number-space{cursor:default}div.ftable-main-container>div.ftable-bottom-panel span.ftable-page-size-change{margin-left:5px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-goto-page{margin-left:5px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-goto-page input[type=text]{width:22px}div.ftable-main-container>div.ftable-bottom-panel span.ftable-page-info{vertical-align:middle}div.ftable-main-container div.ftable-column-resize-bar{opacity:.5;position:absolute;width:1px;background-color:#000}form.ftable-dialog-form div.ftable-input-field-container{padding:2px 0 3px 0;border-bottom:1px solid #ddd}form.ftable-dialog-form div.ftable-input-field-container:last-child{border:none}form.ftable-dialog-form div.ftable-input-label{padding:2px 3px;font-size:1.1em;color:#666}form.ftable-dialog-form div.ftable-input{padding:2px}form.ftable-dialog-form span.ftable-option-text-clickable{position:relative;top:-2px}form.ftable-dialog-form div.ftable-textarea-input textarea{width:300px;min-height:60px}form.ftable-dialog-form div.ftable-checkbox-input span,form.ftable-dialog-form div.ftable-radio-input span{padding-left:4px}form.ftable-dialog-form div.ftable-checkbox-input input,form.ftable-dialog-form div.ftable-radio-input input,form.ftable-dialog-form span.ftable-option-text-clickable{cursor:pointer}.ftable-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5);z-index:1000;display:none}.ftable-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#fff;padding:20px;border-radius:5px;box-shadow:0 2px 10px rgba(0,0,0,.3);z-index:1001;max-width:90%;max-height:90vh;overflow:auto}.ftable-modal-header{margin-bottom:15px;margin-top:0;padding-bottom:10px;border-bottom:1px solid #eee}.ftable-modal-footer{margin-top:15px;padding-top:10px;border-top:1px solid #eee;text-align:right}.ftable-modal-close{position:absolute;top:10px;right:10px;cursor:pointer;font-size:28px;font-weight:700;color:#aaa}.ftable-busy-modal{padding:0}.ftable-dialog-button{opacity:.8;border:1px solid #ccc;padding:5px;margin:5px}.ftable-dialog-button:hover{background-color:#dedede}div.ftable-busy-message{cursor:wait;margin:0}div.ftable-contextmenu-overlay{position:fixed;left:0;top:0;width:100%;height:100%;z-index:100}.ftable-table-div{display:block;overflow-x:auto}.ftable-table-div>table{overflow:hidden}.ftable-toolbarsearch{width:90%;min-width:fit-content}th.ftable-toolbarsearch-reset{text-align:center!important}div.ftable-column-selection-container{position:absolute;border:1px solid #c8c8c8;background:#fff;color:#000;z-index:101;padding:5px}div.ftable-column-selection-container ul.ftable-column-select-list{margin:0;padding:0;list-style:none}div.ftable-column-selection-container ul.ftable-column-select-list li{margin:0;padding:2px 0}div.ftable-column-selection-container ul.ftable-column-select-list li label span{position:relative;top:-1px;margin-left:4px}div.ftable-column-selection-container ul.ftable-column-select-list li input[type=checkbox]{cursor:pointer}.ftable-yesno-check-wrapper{display:flex;align-items:center}.ftable-yesno-check-fixedlabel,.ftable-yesno-check-text{margin-left:4px}.ftable-yesno-check-text:before{content:attr(data-no)}.ftable-yesno-check-input:checked~.ftable-yesno-check-text:before{content:attr(data-yes)}.ftable-multiselect-container{position:relative;display:inline-block;width:100%;min-width:200px}.ftable-multiselect-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:0 0;z-index:9999}.ftable-multiselect-display{display:flex;align-items:center;background:#fff;border:1px solid #ccc;border-radius:4px;cursor:pointer;min-height:38px;padding:4px 30px 4px 8px;position:relative}.ftable-multiselect-display:hover{border-color:#999}.ftable-multiselect-selected{display:flex;flex-wrap:wrap;gap:4px;flex:1;align-items:center}.ftable-multiselect-placeholder{color:#555}.ftable-multiselect-tag{display:inline-flex;align-items:center;background:#e3f2fd;border:1px solid #90caf9;border-radius:3px;padding:2px 6px;font-size:13px;gap:6px;max-width:100%}.ftable-multiselect-tag-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ftable-multiselect-tag-remove{cursor:pointer;font-weight:700;color:#1976d2;font-size:18px;line-height:1;padding:0 2px;user-select:none}.ftable-multiselect-tag-remove:hover{color:#d32f2f}.ftable-multiselect-count{color:#666;font-size:12px;margin-left:4px;white-space:nowrap}.ftable-multiselect-toggle{position:absolute;right:0;background:0 0;border:none;cursor:pointer;padding:4px;color:#666;font-size:10px;line-height:1}.ftable-multiselect-toggle:hover{color:#333}.ftable-multiselect-dropdown{background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 4px 6px rgba(0,0,0,.1);max-height:200px;overflow-y:auto;z-index:10000}.ftable-multiselect-option{display:flex;align-items:center;padding:4px 8px;cursor:pointer;user-select:none;gap:4px}.ftable-multiselect-option:hover{background:#f5f5f5}.ftable-multiselect-checkbox{cursor:pointer;margin:0;flex-shrink:0}.ftable-multiselect-label{cursor:pointer;flex:1;margin:0}.ftable-multiselect-search .ftable-multiselect-display{min-height:22px}@media (max-width:768px){.ftable-multiselect-dropdown{max-height:200px}.ftable-multiselect-tag{font-size:12px}}.ftable-multiselect-dropdown::-webkit-scrollbar{width:8px}.ftable-multiselect-dropdown::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.ftable-multiselect-dropdown::-webkit-scrollbar-thumb{background:#888;border-radius:4px}.ftable-multiselect-dropdown::-webkit-scrollbar-thumb:hover{background:#555}div.ftable-main-container div.ftable-title div.ftable-title-text{font-size:16px;font-weight:700}div.ftable-busy-message{color:#000;background-color:#ddd;font-size:1.25em}
@@ -723,9 +723,20 @@
723
723
 
724
724
  /* Custom Multi-Select Styles */
725
725
  .ftable-multiselect-container {
726
- position: relative;
727
- display: inline-block;
726
+ position: relative; display: inline-block;
728
727
  width: 100%;
728
+ min-width: 200px;
729
+ }
730
+
731
+ /* Overlay for closing dropdown when clicking outside */
732
+ .ftable-multiselect-overlay {
733
+ position: fixed;
734
+ top: 0;
735
+ left: 0;
736
+ right: 0;
737
+ bottom: 0;
738
+ background: transparent;
739
+ z-index: 9999;
729
740
  }
730
741
 
731
742
  .ftable-multiselect-display {
@@ -744,11 +755,6 @@
744
755
  border-color: #999;
745
756
  }
746
757
 
747
- .ftable-multiselect-display:focus-within {
748
- border-color: #4CAF50;
749
- box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
750
- }
751
-
752
758
  .ftable-multiselect-selected {
753
759
  display: flex;
754
760
  flex-wrap: wrap;
@@ -759,7 +765,6 @@
759
765
 
760
766
  .ftable-multiselect-placeholder {
761
767
  color: #555;
762
- font-weight: normal;
763
768
  }
764
769
 
765
770
  .ftable-multiselect-tag {
@@ -818,13 +823,14 @@
818
823
  }
819
824
 
820
825
  .ftable-multiselect-dropdown {
821
- position: relative;
826
+ /* Position is set dynamically via JavaScript */
822
827
  background: white;
823
828
  border: 1px solid #ccc;
824
829
  border-radius: 4px;
825
830
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
826
831
  max-height: 200px;
827
832
  overflow-y: auto;
833
+ z-index: 10000;
828
834
  }
829
835
 
830
836
  .ftable-multiselect-option {
@@ -833,7 +839,7 @@
833
839
  padding: 4px 8px;
834
840
  cursor: pointer;
835
841
  user-select: none;
836
- gap: 8px;
842
+ gap: 4px;
837
843
  }
838
844
 
839
845
  .ftable-multiselect-option:hover {
@@ -854,7 +860,7 @@
854
860
 
855
861
  /* For search toolbar version */
856
862
  .ftable-multiselect-search .ftable-multiselect-display {
857
- min-height: 20px;
863
+ min-height: 22px;
858
864
  }
859
865
 
860
866
  /* Responsive adjustments */