Files
ludikevent_crm/assets/libs/initTomSelect.js
Serreau Jovann 034210d91d ```
 feat(Formules.php): Ajoute relation OneToOne avec FormulesRestriction.
 feat(Dashboard/FormulesController.php): Gère restrictions formules et formulaire.
🎨 refactor(template/formules): Améliore interface configuration restriction formule.
🐛 fix(assets/RepeatLine.js): Corrige réinitialisation TomSelect et selects "Type".
 feat(assets/initTomSelect.js): Gère cache options et init TomSelect.
```
2026-01-28 16:00:35 +01:00

127 lines
5.7 KiB
JavaScript

import TomSelect from "tom-select";
// Cache séparé pour éviter les conflits entre produits et options
let productCache = null;
let optionsCache = null;
/**
* Initialise TomSelect sur un élément ou un groupe d'éléments
*/
export function initTomSelect(parent = document) {
parent.querySelectorAll('select').forEach((el) => {
// --- CLAUSES DE GARDE ---
// On ignore si déjà initialisé OU si l'élément possède l'attribut "is"
if (el.tomselect || el.hasAttribute('ds')) return;
// --- CONFIGURATION PRODUITS ---
if (el.getAttribute('data-load') === "product") {
const setupSelect = (data) => {
new TomSelect(el, {
valueField: 'id',
labelField: 'name',
searchField: 'name',
options: data,
maxOptions: null,
onChange: (id) => {
if (!id) return;
const product = data.find(p => String(p.id) === String(id));
if (product) {
const row = el.closest('.form-repeater__row') || el.closest('fieldset');
if (!row) return;
const priceInput = row.querySelector('input[name*="[price_ht]"]');
const priceSupInput = row.querySelector('input[name*="[price_sup_ht]"]');
if (priceInput) {
priceInput.value = product.price1day;
priceInput.dispatchEvent(new Event('input', { bubbles: true }));
}
if (priceSupInput) {
priceSupInput.value = product.priceSup;
priceSupInput.dispatchEvent(new Event('input', { bubbles: true }));
}
}
},
render: {
option: (data, escape) => `
<div class="flex items-center gap-3 py-2 px-3 border-b border-slate-800/50">
<img src="${escape(data.image)}" class="w-8 h-8 object-cover rounded shadow-sm">
<div class="flex flex-col">
<div class="text-[13px] font-bold text-white">${escape(data.name)}</div>
<div class="text-[10px] text-slate-400">J1: ${escape(data.price1day)}€ | Sup: ${escape(data.priceSup)}€</div>
</div>
</div>`,
item: (data, escape) => `<div class="text-blue-400 font-bold flex items-center gap-2"><span class="w-1.5 h-1.5 rounded-full bg-blue-500"></span>${escape(data.name)}</div>`
}
});
};
if (productCache) {
setupSelect(productCache);
} else {
fetch("/crm/products/json")
.then(r => r.json())
.then(data => {
productCache = data;
setupSelect(data);
});
}
}
// --- CONFIGURATION OPTIONS ---
else if (el.getAttribute('data-load') === "options") {
const setupSelect = (data) => {
new TomSelect(el, {
valueField: 'id',
labelField: 'name',
searchField: 'name',
options: data,
maxOptions: null,
onChange: (id) => {
if (!id) return;
const product = data.find(p => String(p.id) === String(id));
const row = el.closest('.form-repeater__row') || el.closest('fieldset');
if (!row) return;
const priceInput = row.querySelector('input[name*="[price_ht]"]');
if (priceInput) {
priceInput.value = product.price;
priceInput.dispatchEvent(new Event('input', { bubbles: true }));
}
},
render: {
option: (data, escape) => `
<div class="flex items-center gap-3 py-2 px-3 border-b border-slate-800/50">
<img src="${escape(data.image)}" class="w-8 h-8 object-cover rounded shadow-sm">
<div class="flex flex-col">
<div class="text-[13px] font-bold text-white">${escape(data.name)}</div>
<div class="text-[10px] text-slate-400">${escape(data.price)}€</div>
</div>
</div>`,
item: (data, escape) => `<div class="text-blue-400 font-bold flex items-center gap-2"><span class="w-1.5 h-1.5 rounded-full bg-blue-500"></span>${escape(data.name)}</div>`
}
});
};
if (optionsCache) {
setupSelect(optionsCache);
} else {
fetch("/crm/options/json")
.then(r => r.json())
.then(data => {
optionsCache = data;
setupSelect(data);
});
}
}
// --- AUTRES SELECTS STANDARDS ---
else {
new TomSelect(el, {
controlInput: null,
allowEmptyOption: true,
highlight: true,
plugins: ['dropdown_input'],
});
}
});
}