1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = ["principale", "secondaires"] 5 6 connect() { 7 console.log("Principale target:", this.principaleTarget); 8 console.log("Secondaires target:", this.secondairesTarget); 9 10 if (this.hasPrincipaleTarget) { 11 // Ãcouter l'événement change sur le select principal 12 this.principaleTarget.addEventListener("change", () => { 13 this.syncPrincipaleToSecondaires(); 14 }); 15 16 // Observer également les mutations pour détecter les changements programmatiques 17 this.observeChanges(this.principaleTarget, () => { 18 this.syncPrincipaleToSecondaires(); 19 }); 20 } 21 22 if (this.hasSecondairesTarget) { 23 const tomSelect = this.secondairesTarget.tomselect; 24 if (tomSelect) { 25 tomSelect.on('item_add', (value) => { 26 let option = this.secondairesTarget.querySelector(`option[value="${value}"]`); 27 if (!option) { 28 option = document.createElement("option"); 29 option.value = value; 30 option.text = tomSelect.options[value]?.text ?? 'Inconnu'; 31 option.selected = true; 32 this.secondairesTarget.appendChild(option); 33 } else { 34 option.selected = true; 35 } 36 }); 37 38 tomSelect.on('item_remove', (value) => { 39 const option = this.secondairesTarget.querySelector(`option[value="${value}"]`); 40 if (option) { 41 option.remove(); // Ou juste option.selected = false; selon ton besoin 42 } 43 }); 44 } 45 // Ãcouter l'événement change sur le select secondaire 46 this.secondairesTarget.addEventListener("change", () => { 47 this.syncSecondairesToPrincipale(); 48 }); 49 50 // Observer également les mutations pour détecter les changements programmatiques 51 this.observeChanges(this.secondairesTarget, () => { 52 this.syncSecondairesToPrincipale(); 53 }); 54 } 55 } 56 57 observeChanges(element, callback) { 58 const observer = new MutationObserver(() => callback()); 59 observer.observe(element, { attributes: true, childList: true, subtree: true }); 60 } 61 62 syncPrincipaleToSecondaires() { 63 const principale = this.principaleTarget; 64 const secondaires = this.secondairesTarget; 65 66 const principaleValue = principale.value; 67 if (!principaleValue) return; 68 69 const tomSelect = secondaires.tomselect; 70 71 if (tomSelect) { 72 const alreadySelected = tomSelect.items.includes(principaleValue); 73 if (!alreadySelected) { 74 const existingOption = tomSelect.options[principaleValue]; 75 const principaleLabel = principale.selectedOptions[0]?.text ?? 'Nom inconnu'; 76 77 if (!existingOption) { 78 // Ajoute dans TomSelect 79 tomSelect.addOption({ 80 value: principaleValue, 81 text: principaleLabel, 82 }); 83 } 84 85 // Ajoute à TomSelect UI 86 tomSelect.addItem(principaleValue); 87 88 // ð¥ S'assure que le <select> natif contient l'option selected 89 const nativeOption = [...secondaires.options].find(o => o.value === principaleValue); 90 if (!nativeOption) { 91 const opt = document.createElement("option"); 92 opt.value = principaleValue; 93 opt.text = principaleLabel; 94 opt.selected = true; 95 secondaires.appendChild(opt); 96 } else { 97 nativeOption.selected = true; 98 } 99 } 100 } 101 } 102 103 syncSecondairesToPrincipale() { 104 const principale = this.principaleTarget; 105 const secondaires = this.secondairesTarget; 106 107 const secondaireTomSelect = secondaires.tomselect; 108 const principaleTomSelect = principale.tomselect; 109 110 const selectedSecondaires = secondaireTomSelect.items; 111 112 // Si le champ principal est vide et qu'il y a des valeurs dans le secondaire 113 if (principaleTomSelect.items.length === 0 && selectedSecondaires.length > 0) { 114 const firstValue = selectedSecondaires[0]; 115 116 if (!principaleTomSelect.options[firstValue]) { 117 // Ajouter l'option si elle n'existe pas 118 principaleTomSelect.addOption({ 119 value: firstValue, 120 text: secondaireTomSelect.options[firstValue]?.text || 'Valeur inconnue' 121 }); 122 } 123 124 principaleTomSelect.setValue(firstValue); 125 } 126 127 // Si la valeur principale nâest plus dans les secondaires sélectionnées 128 const principaleValue = principaleTomSelect.items[0]; 129 130 if (principaleValue && !selectedSecondaires.includes(principaleValue)) { 131 const newValue = selectedSecondaires[0] || ''; 132 133 if (newValue) { 134 if (!principaleTomSelect.options[newValue]) { 135 principaleTomSelect.addOption({ 136 value: newValue, 137 text: secondaireTomSelect.options[newValue]?.text || 'Valeur inconnue' 138 }); 139 } 140 141 principaleTomSelect.setValue(newValue); 142 } else { 143 principaleTomSelect.clear(); 144 } 145 } 146 } 147}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.