const ComboBoxWidget = (() => { let tempIdCounter = -1; function initComboBox(ns, config = {}) { const input = document.querySelector(`#${ns}-input`); const list = document.querySelector(`#${ns}-list`); const addBtn = document.querySelector(`#${ns}-add`); const removeBtn = document.querySelector(`#${ns}-remove`); let currentlyEditing = null; let tempIdCounter = -1; if (!input || !list || !addBtn || !removeBtn) { console.warn(`ComboBoxWidget: Missing elements for namespace '${ns}'`); return; } function updateAddButtonIcon() { const iconEl = addBtn.querySelector('.icon-state'); const iconClass = currentlyEditing ? 'bi-pencil' : 'bi-plus-lg'; iconEl.classList.forEach(cls => { if (cls.startsWith('bi-') && cls !== 'icon-state') { iconEl.classList.remove(cls); } }); iconEl.classList.add(iconClass); } input.addEventListener('input', () => { addBtn.disabled = input.value.trim() === ''; updateAddButtonIcon(); }); list.addEventListener('change', () => { const selected = list.selectedOptions; removeBtn.disabled = selected.length === 0; if (selected.length === 1) { input.value = selected[0].textContent; currentlyEditing = selected[0]; addBtn.disabled = input.value.trim() === ''; } else { input.value = ''; currentlyEditing = null; addBtn.disabled = true; } updateAddButtonIcon(); }); addBtn.addEventListener('click', () => { const newItem = input.value.trim(); if (!newItem) return; if (currentlyEditing) { if (config.onEdit) { config.onEdit(currentlyEditing, newItem); } else { currentlyEditing.textContent = newItem; } currentlyEditing = null; } else { const option = document.createElement('option'); option.textContent = newItem; option.value = tempIdCounter--; if (config.onAdd) { config.onAdd(option); } list.appendChild(option); } input.value = ''; addBtn.disabled = true; removeBtn.disabled = true; updateAddButtonIcon(); if (config.sort !== false) { sortOptions(list); } }); removeBtn.addEventListener('click', () => { Array.from(list.selectedOptions).forEach(option => { if (config.onRemove) { config.onRemove(option); } option.remove(); }); currentlyEditing = null; input.value = ''; addBtn.disabled = true; removeBtn.disabled = true; updateAddButtonIcon(); }); function sortOptions(selectElement) { const sorted = Array.from(selectElement.options) .sort((a, b) => a.text.localeCompare(b.text)); selectElement.innerHTML = ''; sorted.forEach(option => selectElement.appendChild(option)); } } return { initComboBox }; })();