1/** 2 * Filter Form â Dropdowns à checkboxes (multi-instances / scoped par bloc) 3 */ 4 5/** 6 * Point d'entrée : à appeler avec le bloc racine en contexte 7 * @param {HTMLElement} context - Le bloc .archive-block[data-instance] 8 */ 9function initFilterForm(context = document) { 10 11 const selectWrappers = context.querySelectorAll( 12 '.form-filters__form .select-wrapper' 13 ); 14 if (!selectWrappers.length) return; 15 16 // Init chaque select-wrapper 17 selectWrappers.forEach(wrapper => initForm(wrapper)); 18 19 // Bouton reset scopé au bloc 20 const resetLinks = context.querySelectorAll( 21 '.form-filters__form .btn-reset' 22 ); 23 resetLinks.forEach(resetLink => { 24 resetLink.addEventListener('click', e => { 25 e.preventDefault(); 26 selectWrappers.forEach(wrapper => resetFilterForm(wrapper)); 27 }); 28 }); 29} 30 31/** 32 * Initialise un select-wrapper 33 * @param {HTMLElement} wrapper 34 */ 35function initForm(wrapper) { 36 const trigger = wrapper.querySelector('.input-select'); 37 const dropdown = wrapper.querySelector('.select-dropdown'); 38 const checkboxes = wrapper.querySelectorAll( 39 '.select-dropdown__select-option input' 40 ); 41 42 if (!trigger || !dropdown) return; 43 44 // ââ Toggle dropdown ââââââââââââââââââââââââââââââââââââââââââ 45 trigger.addEventListener('click', e => { 46 e.stopPropagation(); 47 const isOpen = dropdown.classList.contains('is-open'); 48 49 // Ferme les autres dropdowns du même formulaire 50 const form = wrapper.closest('.form-filters__form'); 51 if (form) { 52 form.querySelectorAll('.select-wrapper').forEach(sibling => { 53 if (sibling !== wrapper) { 54 closeDropdown( 55 sibling.querySelector('.input-select'), 56 sibling.querySelector('.select-dropdown') 57 ); 58 } 59 }); 60 } 61 62 dropdown.classList.toggle('is-open', !isOpen); 63 trigger.setAttribute('aria-expanded', String(!isOpen)); 64 }); 65 66 // ââ Fermeture au clic extérieur (une seule condition) ââââââââ 67 document.addEventListener('click', e => { 68 if (!wrapper.contains(e.target)) { 69 closeDropdown(trigger, dropdown); 70 } 71 }); 72 73 // ââ Mise à jour placeholder + fermeture à chaque sélection ââ 74 checkboxes.forEach(cb => { 75 cb.addEventListener('change', () => { 76 updatePlaceholder(wrapper); 77 closeDropdown(trigger, dropdown); 78 }); 79 }); 80} 81 82/** 83 * Réinitialise un select-wrapper (checkboxes + placeholder + état) 84 * @param {HTMLElement} wrapper 85 */ 86function resetFilterForm(wrapper) { 87 const trigger = wrapper.querySelector('.input-select'); 88 const dropdown = wrapper.querySelector('.select-dropdown'); 89 const checkboxes = wrapper.querySelectorAll( 90 '.select-dropdown__select-option input' 91 ); 92 93 checkboxes.forEach(cb => (cb.checked = false)); 94 updatePlaceholder(wrapper); 95 closeDropdown(trigger, dropdown); 96} 97 98/** 99 * Met à jour le placeholder avec les labels des options cochées 100 * @param {HTMLElement} wrapper 101 */ 102function updatePlaceholder(wrapper) { 103 const placeholder = wrapper.querySelector('.input-select__placeholder'); 104 const checkboxes = wrapper.querySelectorAll( 105 '.select-dropdown__select-option input' 106 ); 107 108 if (!placeholder) return; 109 110 const selectedLabels = Array.from(checkboxes) 111 .filter(cb => cb.checked) 112 .map(cb => cb.dataset.label); 113 114 placeholder.textContent = selectedLabels.length 115 ? selectedLabels.join(', ') 116 : placeholder.dataset.placeholder; 117} 118 119/** 120 * Ferme un dropdown 121 * @param {HTMLElement} trigger 122 * @param {HTMLElement} dropdown 123 */ 124function closeDropdown(trigger, dropdown) { 125 if (!trigger || !dropdown) return; 126 dropdown.classList.remove('is-open'); 127 trigger.setAttribute('aria-expanded', 'false'); 128} 129 130export { initFilterForm };
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.