✨ feat(Product.php): Ajoute relation DevisLine et méthodes associées en français. ✨ feat(DevisLine.php): Ajoute propriétés et relations pour ligne de devis en français. ✨ feat(DevisController.php): Intègre génération PDF et ajout de lignes de devis en français. 🎨 style: Améliore la mise en page et l'esthétique de l'interface admin en français. ✨ feat: Initialise TomSelect et gère les adresses client dans DevisManager en français. 🐛 fix: Corrige l'initialisation de TomSelect et la gestion des lignes répétées en français. ✅ test: Ajoute génération du bon pour accord et signature en français. ```
126 lines
3.9 KiB
JavaScript
126 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;
|
|
|
|
// Création de la nouvelle ligne
|
|
let newRow = this.createFromHTML(this.rowHTML);
|
|
newRow.removeAttribute('id');
|
|
|
|
// Nettoyage spécifique pour TomSelect avant insertion
|
|
// Si on clone une ligne qui avait déjà TomSelect, on reset le select
|
|
newRow.querySelectorAll('select').forEach(select => {
|
|
// Supprimer les classes et éléments injectés par TomSelect si présents dans le template
|
|
select.classList.remove('tomselect', 'ts-hidden-visually');
|
|
select.innerHTML = '<option value="">Sélectionner...</option>';
|
|
// Supprimer le wrapper TomSelect s'il a été cloné par erreur
|
|
const wrapper = select.nextElementSibling;
|
|
if (wrapper && wrapper.classList.contains('ts-wrapper')) {
|
|
wrapper.remove();
|
|
}
|
|
});
|
|
|
|
this.setUpRow(newRow);
|
|
this.$refs.rows.appendChild(newRow);
|
|
|
|
// Réinitialisation des valeurs
|
|
newRow.querySelectorAll('input,textarea,select').forEach(el => {
|
|
el.value = "";
|
|
if (el.tagName === 'SELECT') el.selectedIndex = 0;
|
|
});
|
|
|
|
// --- INITIALISATION TOMSELECT SUR LA NOUVELLE LIGNE ---
|
|
initTomSelect(newRow);
|
|
|
|
this.updateFieldNames();
|
|
this.updateAddButton();
|
|
|
|
// Focus sur le premier élément de la nouvelle ligne
|
|
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;
|
|
}
|
|
}
|