PageSourceSearch

https://www.krautwiller.fr/assets/controllers/sondage-form_controller-2ceaa1d7b5302a4f41ecab3f1731dfbd.js

js krautwiller.fr collected 2026-10-03 01:20:50 UTC 10,791 bytes, 295 lines download raw bytes

1import {Controller} from "@hotwired/stimulus";
2
3export default class extends Controller {
4    static targets = ["questions", "dateDebutInput", "choiceIcon"];
5    static values = {
6        prototypeQuestion: String,
7    };
8
9    connect() {
10        this.updateQuestionIndices();
11        this.initializeIcon();
12        // Document.querySelector('.form_sondage').addEventListener('submit', (e))
13    }
14
15    choiceIconTargetConnected(element) {
16        this.initializeIcon(element.closest('.choice-item'));
17    }
18
19    //Ajout d'une question via les boutons
20    addQuestion(event) {
21        event.preventDefault();
22        const questionType = event.params.questionType || "reponse_courte";
23
24        // Étape 1 : Ajouter la div
25        const newElement = this.createQuestionElement();
26
27        if (!newElement) {
28            console.error("Le nouvel élément est nul. Vérifiez le prototype.");
29            return;
30        }
31
32        this.questionsTarget.appendChild(newElement);
33
34        // Étape 2 : Mettre le type selecteur de de question au bon type
35        this.setQuestionType(newElement, questionType);
36
37        // Étape 3 : Renuméroter
38        this.updateQuestionIndices();
39    }
40
41    createQuestionElement() {
42        const tempDiv = document.createElement("div");
43        tempDiv.innerHTML = this.prototypeQuestionValue;
44        return tempDiv.firstElementChild;
45    }
46
47    setQuestionType(element, questionType) {
48        const typeSelect = element.querySelector(".selection-type");
49        if (typeSelect) {
50            for (let option of typeSelect.options) {
51                if (option.getAttribute("code") === questionType) {
52                    typeSelect.value = option.value;
53                    break;
54                }
55            }
56            this.updateQuestionDisplay(null, typeSelect);
57        }
58    }
59
60    updateQuestionDisplay(event = null, typeSelect = null) {
61        if (event != null) {
62            typeSelect = event.currentTarget;
63        }
64        const questionElement = typeSelect.closest('.question-item');
65        const selectedOption = typeSelect.options[typeSelect.selectedIndex];
66        const questionType = selectedOption.getAttribute("code");
67
68        const choixContainer = questionElement.querySelector(".hide-choix");
69
70        const requiresChoices = ["choix_simple", "choix_multiple"].includes(questionType);
71
72        if (choixContainer) {
73            if (requiresChoices) {
74                choixContainer.classList.remove("d-none");
75            } else {
76                choixContainer.classList.add("d-none");
77            }
78        }
79
80        // Mise à jour des icônes des choix
81        this.updateChoiceIcons(questionElement, questionType);
82    }
83
84
85    remove(event) {
86        event.preventDefault();
87        const questionElement = event.currentTarget.closest('.question-item');
88
89        questionElement.remove();
90
91        // Renuméroter
92        this.updateQuestionIndices();
93    }
94
95    moveUp(event) {
96        event.preventDefault();
97        const questionElement = event.currentTarget.closest('.question-item');
98        if (!questionElement) {
99            return;
100        }
101
102        const previousElement = questionElement.previousElementSibling;
103        if (previousElement && previousElement.classList.contains('question-item')) {
104            this.questionsTarget.insertBefore(questionElement, previousElement);
105
106            // Renuméroter
107            this.updateQuestionIndices();
108        }
109    }
110
111    moveDown(event) {
112        event.preventDefault();
113        const questionElement = event.currentTarget.closest('.question-item');
114        if (!questionElement) {
115            return;
116        }
117        const nextElement = questionElement.nextElementSibling;
118        if (nextElement && nextElement.classList.contains('question-item')) {
119            this.questionsTarget.insertBefore(nextElement, questionElement);
120
121            // Renuméroter
122            this.updateQuestionIndices();
123        }
124    }
125
126    duplicate(event) {
127        event.preventDefault();
128        const questionElement = event.currentTarget.closest('.question-item');
129        if (!questionElement) {
130            return;
131        }
132
133        // Copier la div
134        const clone = questionElement.cloneNode(true);
135
136        // Insérer le clone
137        questionElement.insertAdjacentElement('afterend', clone);
138
139        // Renuméroter
140        this.updateQuestionIndices();
141    }
142
143    updateQuestionIndices() {
144        const questionElements = this.questionsTarget.querySelectorAll('.question-item');
145
146        questionElements.forEach((questionElement, questionIndex) => {
147            // Mettre à jour l'affichage de l'ordre
148            const displayOrdre = questionElement.querySelector('.display-ordre');
149            if (displayOrdre) {
150                displayOrdre.textContent = questionIndex + 1;
151            }
152
153            // Mettre à jour les indices dans les attributs name et id des champs de la question
154            this.updateElementIndices(questionElement, questionIndex);
155
156            // Mettre à jour l'indice dans l'input hidden 'ordre' de la question
157            const ordreInput = questionElement.querySelector('input[name$="[ordre]"]');
158            if (ordreInput) {
159                ordreInput.value = questionIndex;
160            }
161
162            const choiceElements = questionElement.querySelectorAll('.choice-item');
163            choiceElements.forEach((choiceElement, choiceIndex) => {
164                this.updateElementIndices(choiceElement, questionIndex, choiceIndex);
165
166                // Mettre à jour l'indice dans l'input hidden 'ordre' du choix
167                const ordreChoiceInput = choiceElement.querySelector('input[name$="[ordre]"]');
168                if (ordreChoiceInput) {
169                    ordreChoiceInput.value = choiceIndex;
170                }
171            });
172        });
173    }
174
175    updateElementIndices(element, questionIndex, choiceIndex = null) {
176        // Mettre à jour l'élément lui-même
177        this.updateAttributes(element, questionIndex, choiceIndex);
178
179        // Mettre à jour les descendants
180        element.querySelectorAll('[name], [id]').forEach((input) => {
181            this.updateAttributes(input, questionIndex, choiceIndex);
182        });
183    }
184
185    updateAttributes(element, questionIndex, choiceIndex) {
186        let name = element.getAttribute('name');
187        let id = element.getAttribute('id');
188        let newId = '';
189
190        // Remplacer les placeholders dans 'name' et 'id'
191        if (name) {
192            let newName = name.replaceAll(/\[questions\]\[(__QUESTION_PROTOTYPE__|\d+)\]/g, `[questions][${questionIndex}]`);
193            if (choiceIndex !== null) {
194                newName = newName.replaceAll(/\[choices\]\[(__CHOIX_PROTOTYPE__|\d+)\]/g, `[choices][${choiceIndex}]`);
195            }
196            element.setAttribute('name', newName);
197        }
198
199        if (id) {
200            newId = id.replaceAll(/_questions_(__QUESTION_PROTOTYPE__|\d+)/g, `_questions_${questionIndex}`);
201            if (choiceIndex !== null) {
202                newId = newId.replaceAll(/_choices_(__CHOIX_PROTOTYPE__|\d+)_/g, `_choices_${choiceIndex}`);
203            }
204            element.setAttribute('id', newId);
205        }
206
207        // Mettre à jour l'attribut 'for' des labels associés
208        if (id) {
209            const labels = element.closest('.question-item').querySelectorAll(`label[for="${id}"]`);
210            labels.forEach((label) => {
211                label.setAttribute('for', newId);
212            });
213        }
214    }
215
216    toggleDateDebut(event) {
217        const input = this.dateDebutInputTarget.querySelector('input');
218        input.required = event.target.checked;
219        if (event.target.checked) {
220            this.dateDebutInputTarget.classList.remove("d-none");
221        } else {
222            this.dateDebutInputTarget.classList.add("d-none");
223            input.value = '';
224        }
225    }
226
227
228    // Méthode pour mettre à jour les icônes des choix en fonction du type de question
229    updateChoiceIcons(questionElement, questionType) {
230        const choiceIcons = questionElement.querySelectorAll('.icon-choix');
231        choiceIcons.forEach(iconElement => {
232            this.changeIconeChoice(iconElement, questionType)
233        });
234    }
235
236    changeIconeChoice(iconElement, questionType) {
237        iconElement.innerHTML = this.getIconHTML(questionType);
238    }
239
240    // Méthode pour initialiser les icônes de tous les choix existants lors du chargement
241    initializeIcon(choiceElement = null) {
242        if (choiceElement) {
243            const questionElement = choiceElement.closest('.question-item');
244            const typeSelect = questionElement.querySelector('.selection-type');
245            const questionType = typeSelect ? typeSelect.options[typeSelect.selectedIndex].getAttribute('co
245de') : null;
246            if (questionType) {
247                const iconElement = choiceElement.querySelector('[data-sondage-form-target="choiceIcon"]');
248                if (iconElement) {
249                    this.changeIconeChoice(iconElement, questionType);
250                }
251            }
252        } else {
253            this.choiceIconTargets.forEach(iconElement => {
254                const choiceElement = iconElement.closest('.choice-item');
255                const questionElement = choiceElement.closest('.question-item');
256                const typeSelect = questionElement.querySelector('.selection-type');
257                const questionType = typeSelect ? typeSelect.options[typeSelect.selectedIndex].getAttribute('code') : null;
258                console.log(typeSelect)
259                if (questionType) {
260                    this.changeIconeChoice(iconElement, questionType);
261                }
262            });
263        }
264    }
265
266    getIconHTML(type) {
267        const icons = {
268            'choix_simple': '<i class="fa-regular fa-circle-dot fs-3"></i>',
269            'choix_multiple': '<i class="fa-regular fa-square-check fs-3"></i>',
270        };
271        return icons[type] || '';
272    }
273
274    onSubmit(event) {
275        event.preventDefault();
276
277        const questionElements = this.questionsTarget.querySelectorAll('.question-item');
278
279        questionElements.forEach(questionElement => {
280            const typeSelect = questionElement.querySelector('.selection-type');
281            const questionType = typeSelect ? typeSelect.options[typeSelect.selectedIndex].getAttribute('code') : null;
282
283            if (!["choix_simple", "choix_multiple"].includes(questionType)) {
284                questionElement.querySelectorAll('.choix-item').forEach(choice => {
285                    choice.remove();
286                })
287            }
288        });
289        if (typeof this.element.requestSubmit === 'function') {
290            this.element.requestSubmit();
291        } else {
292            this.element.submit();
293        }
294    }
295}

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.