✨ 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. ```
128 lines
3.9 KiB
JavaScript
128 lines
3.9 KiB
JavaScript
import { initTomSelect } from "./initTomSelect.js" // Assure-toi que le chemin est correct
|
|
|
|
export class RepeatLine extends HTMLDivElement {
|
|
connectedCallback() {
|
|
this.$props = this.getProps(this, { maxRows: 20 });
|
|
this.$refs = this.getRefs(this);
|
|
|
|
// On stocke le HTML de la première ligne comme modèle
|
|
this.rowHTML = this.$refs.rows.children[0].outerHTML;
|
|
|
|
this.init();
|
|
}
|
|
|
|
setUpRow(row) {
|
|
const rowRefs = this.getRefs(row);
|
|
|
|
if (rowRefs.removeButton) {
|
|
rowRefs.removeButton.onclick = (e) => {
|
|
e.preventDefault();
|
|
this.removeRow(row);
|
|
};
|
|
}
|
|
}
|
|
|
|
updateAddButton() {
|
|
if (this.$refs.rows.children.length >= this.$props.maxRows) {
|
|
this.$refs.addButton.setAttribute('disabled', '');
|
|
return;
|
|
}
|
|
this.$refs.addButton.removeAttribute('disabled');
|
|
}
|
|
|
|
updateFieldNames() {
|
|
[...this.$refs.rows.children].forEach((el, index) => {
|
|
el.querySelectorAll('[name]').forEach(input => {
|
|
const newName = input.getAttribute('name').replace(/\[\d+\]/gm, `[${index}]`);
|
|
input.setAttribute('name', newName);
|
|
});
|
|
});
|
|
}
|
|
|
|
addRow() {
|
|
if (!this.rowHTML || this.$refs.rows.children.length >= this.$props.maxRows) return;
|
|
|
|
let newRow = this.createFromHTML(this.rowHTML);
|
|
newRow.removeAttribute('id');
|
|
|
|
newRow.querySelectorAll('select').forEach(select => {
|
|
// 1. Si c'est un select TomSelect (sans attribut 'is')
|
|
if (!select.hasAttribute('ds')) {
|
|
select.classList.remove('tomselect', 'ts-hidden-visually');
|
|
select.innerHTML = '<option value="">Sélectionner...</option>';
|
|
|
|
const wrapper = select.nextElementSibling;
|
|
if (wrapper && wrapper.classList.contains('ts-wrapper')) {
|
|
wrapper.remove();
|
|
}
|
|
}
|
|
// 2. Si c'est votre select "Type" (avec l'attribut 'is')
|
|
else {
|
|
// On ne touche PAS au innerHTML pour garder les options (Structure, etc.)
|
|
select.value = ""; // On remet juste à zéro la sélection
|
|
}
|
|
});
|
|
|
|
this.setUpRow(newRow);
|
|
this.$refs.rows.appendChild(newRow);
|
|
|
|
// Réinitialisation des autres champs
|
|
newRow.querySelectorAll('input,textarea').forEach(el => {
|
|
el.value = "";
|
|
});
|
|
|
|
// Initialisation TomSelect uniquement sur ce qui doit l'être
|
|
initTomSelect(newRow);
|
|
|
|
this.updateFieldNames();
|
|
this.updateAddButton();
|
|
|
|
const firstInput = newRow.querySelector('input,textarea,select');
|
|
if (firstInput) firstInput.focus();
|
|
}
|
|
|
|
removeRow(row) {
|
|
if (this.$refs.rows.children.length <= 1) return;
|
|
|
|
// Détruire l'instance TomSelect pour libérer la mémoire avant de supprimer le DOM
|
|
row.querySelectorAll('select').forEach(select => {
|
|
if (select.tomselect) {
|
|
select.tomselect.destroy();
|
|
}
|
|
});
|
|
|
|
row.remove();
|
|
this.updateFieldNames();
|
|
this.updateAddButton();
|
|
}
|
|
|
|
init() {
|
|
this.setUpRow(this.$refs.rows.children[0]);
|
|
|
|
this.$refs.addButton.onclick = (e) => {
|
|
e.preventDefault();
|
|
this.addRow();
|
|
}
|
|
|
|
this.updateFieldNames();
|
|
}
|
|
|
|
getRefs(el) {
|
|
let result = {};
|
|
[...el.querySelectorAll('[data-ref]')].forEach(ref => {
|
|
result[ref.dataset.ref] = ref;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
getProps(el, defaults = {}) {
|
|
return Object.assign(defaults, JSON.parse(el.dataset.props ?? '{}'));
|
|
}
|
|
|
|
createFromHTML(html = '') {
|
|
let element = document.createElement('div');
|
|
element.innerHTML = html.trim();
|
|
return element.firstElementChild;
|
|
}
|
|
}
|