|
| 1 | +@php |
| 2 | + // Generate a unique ID if one isn't provided |
| 3 | + $id = $id ?? 'select-' . uniqid(); |
| 4 | +@endphp |
| 5 | + |
1 | 6 | <select name="{{ $name }}" |
2 | 7 | {{ $attributes->merge(['class' => 'form-select']) }} |
3 | 8 | id="{{ $id }}" |
|
23 | 28 | </select> |
24 | 29 | <div class="invalid-feedback"></div> |
25 | 30 |
|
| 31 | +@push('css') |
| 32 | + <style> |
| 33 | + /* Fix for Tom Select dropdown visibility in Tabler */ |
| 34 | + .ts-dropdown { |
| 35 | + /* Use Tabler's surface background color for the dropdown */ |
| 36 | + background-color: var(--tblr-bg-surface); |
| 37 | + /* Add a border to match Tabler's style */ |
| 38 | + border: 1px solid var(--tblr-border-color); |
| 39 | + /* Add a shadow for depth */ |
| 40 | + box-shadow: var(--tblr-box-shadow); |
| 41 | + /* Ensure the dropdown appears above other page content */ |
| 42 | + z-index: 1050; |
| 43 | + } |
| 44 | + .ts-dropdown .dropdown-content, |
| 45 | + .ts-dropdown .ts-dropdown-content { |
| 46 | + /* Ensure the dropdown content itself is not transparent */ |
| 47 | + background-color: var(--tblr-bg-surface); |
| 48 | + } |
| 49 | + .ts-dropdown .option { |
| 50 | + /* Set text color for options */ |
| 51 | + color: var(--tblr-body-color); |
| 52 | + } |
| 53 | + .ts-dropdown .option.active { |
| 54 | + /* Style for the active/hovered option */ |
| 55 | + background-color: var(--tblr-primary-bg-subtle); |
| 56 | + color: var(--tblr-primary); |
| 57 | + } |
| 58 | + </style> |
| 59 | +@endpush |
| 60 | + |
26 | 61 | @push('js') |
27 | 62 | <script type="module"> |
28 | 63 | document.addEventListener('DOMContentLoaded', () => { |
29 | | - const mainSelect = document.getElementById('{{ $id }}'); |
30 | | - @if($targetDropdown!=null) |
31 | | - const targetSelect = document.getElementById('{{ $targetDropdown }}'); |
32 | | - @endif |
| 64 | + // Check if TomSelect is available |
| 65 | + if (!window.TomSelect) return; |
| 66 | +
|
| 67 | + // Initialize Tom Select with Tabler-compatible settings |
| 68 | + const mainSelect = new TomSelect('#{{ $id }}', { |
| 69 | + copyClassesToDropdown: false, |
| 70 | + dropdownParent: 'body', |
| 71 | + controlInput: '<input>', |
| 72 | + create: false, |
| 73 | + sortField: { |
| 74 | + field: "text", |
| 75 | + direction: "asc" |
| 76 | + }, |
| 77 | + render: { |
| 78 | + item: function (data, escape) { |
| 79 | + if (data.customProperties) { |
| 80 | + return '<div><span class="dropdown-item-indicator">' + data.customProperties + "</span>" + escape(data.text) + "</div>"; |
| 81 | + } |
| 82 | + return "<div>" + escape(data.text) + "</div>"; |
| 83 | + }, |
| 84 | + option: function (data, escape) { |
| 85 | + if (data.customProperties) { |
| 86 | + return '<div><span class="dropdown-item-indicator">' + data.customProperties + "</span>" + escape(data.text) + "</div>"; |
| 87 | + } |
| 88 | + return "<div>" + escape(data.text) + "</div>"; |
| 89 | + }, |
| 90 | + } |
| 91 | + }); |
| 92 | +
|
33 | 93 | @if($targetDropdown!=null) |
34 | | - mainSelect.addEventListener('change', () => { |
| 94 | + const targetSelect = new TomSelect('#{{ $targetDropdown }}', { |
| 95 | + copyClassesToDropdown: false, |
| 96 | + dropdownParent: 'body', |
| 97 | + controlInput: '<input>', |
| 98 | + create: false, |
| 99 | + sortField: { |
| 100 | + field: "text", |
| 101 | + direction: "asc" |
| 102 | + }, |
| 103 | + render: { |
| 104 | + item: function (data, escape) { |
| 105 | + if (data.customProperties) { |
| 106 | + return '<div><span class="dropdown-item-indicator">' + data.customProperties + "</span>" + escape(data.text) + "</div>"; |
| 107 | + } |
| 108 | + return "<div>" + escape(data.text) + "</div>"; |
| 109 | + }, |
| 110 | + option: function (data, escape) { |
| 111 | + if (data.customProperties) { |
| 112 | + return '<div><span class="dropdown-item-indicator">' + data.customProperties + "</span>" + escape(data.text) + "</div>"; |
| 113 | + } |
| 114 | + return "<div>" + escape(data.text) + "</div>"; |
| 115 | + }, |
| 116 | + } |
| 117 | + }); |
| 118 | +
|
| 119 | + mainSelect.on('change', () => { |
35 | 120 | @if($targetDataRoute!=null) |
36 | | - targetSelect.dispatchEvent(new CustomEvent('optionsRemoved')); |
| 121 | + // Clear existing options in Tom Select |
| 122 | + targetSelect.clear(); |
| 123 | + targetSelect.clearOptions(); |
| 124 | +
|
| 125 | + // Trigger optionsRemoved event for any child dropdowns |
| 126 | + targetSelect.trigger('optionsRemoved'); |
37 | 127 | @endif |
| 128 | +
|
38 | 129 | axios.get(`{{ route($targetDataRoute) }}`, { |
39 | | - params: {id: mainSelect.value} |
| 130 | + params: {id: mainSelect.getValue()} |
40 | 131 | }) |
41 | 132 | .then(response => { |
42 | | - // The response data is now an object, not an array |
43 | 133 | const products = response.data; |
| 134 | +
|
44 | 135 | Object.entries(products).forEach(([id, value]) => { |
45 | | - const opt = document.createElement('option'); |
46 | | - opt.value = id; |
47 | | - opt.textContent = value; |
48 | | - targetSelect.appendChild(opt); |
| 136 | + targetSelect.addOption({ |
| 137 | + value: id, |
| 138 | + text: value |
| 139 | + }); |
49 | 140 | }); |
| 141 | +
|
| 142 | + targetSelect.refreshOptions(); |
50 | 143 | }) |
51 | 144 | .catch(error => { |
52 | 145 | console.error('Error fetching data:', error); |
53 | 146 | }); |
54 | 147 | }); |
55 | | - targetSelect.addEventListener('optionsRemoved', function () { |
56 | | - while (this.options.length > 0) { |
57 | | - this.remove(0); |
58 | | - } |
59 | | - const childId = this.dataset.child; |
| 148 | +
|
| 149 | + targetSelect.on('optionsRemoved', () => { |
| 150 | + const childId = targetSelect.input.dataset.child; |
60 | 151 | if (childId) { |
61 | | - const childSelect = document.getElementById(childId); |
62 | | - childSelect.dispatchEvent(new CustomEvent('optionsRemoved')); |
| 152 | + const childSelect = document.getElementById(childId).tomselect; |
| 153 | + if (childSelect) { |
| 154 | + childSelect.clear(); |
| 155 | + childSelect.clearOptions(); |
| 156 | + childSelect.trigger('optionsRemoved'); |
| 157 | + } |
63 | 158 | } |
64 | 159 | }); |
65 | 160 | @endif |
|
0 commit comments