PageSourceSearch

https://rurange-les-thionville.fr/js/page/formulaire.js

js rurange-les-thionville.fr collected 2026-10-03 01:01:25 UTC 15,364 bytes, 365 lines download raw bytes

1class Formulaire {
2    /**
3     * Génère un formulaire à partir de sa représentation JSON
4     * @param {number} id - id du formulaire
5     * @param {HTMLElement} parent - élément englobant le formulaire
6     */
7    constructor(id,parent) {
8        this.id = id
9        this.premiere_soumission = true
10
11        this.#charger(id).then(r => {
12            this.sructForm = r
13            this.form = document.createElement('form')
14            // this.form.setAttribute('novalidate', "")
15
16            // positionnement
17            r['blocs'].sort((a, b) => a.position - b.position)
18
19            r['blocs'].forEach(b => {
20                let champ = document.createElement('div')
21                champ.classList.add('champ')
22                
23                if(b['type'] == 'form_texte' || b['type'] == 'form_email'){
24                    champ.classList.add(b['type'])
25
26                    //required
27                    let required = false // required par défaut
28                    if(b.hasOwnProperty("required")) required = b["required"]
29                    let required_etoile = required ? '<abbr class="requis" title="Ce champ est obligatoire">*</abbr>' : ''
30                    
31                    let type = {
32                        "form_texte" : "text",
33                        "form_email" : "email"
34                    }
35                    champ.innerHTML = `
36                        <label
37                            for="form_input_${id}-${b['id']}"
38                            class="label-principal"
39                        >
40                            ${b['label']}
41                            ${required_etoile}
42                        </label>
43                        <input
44                            id="form_input_${id}-${b['id']}"
45                            type="${type[b['type']]}"
46                            name="form_input_${id}-${b['id']}"
47                            ${required ? "required" : ""}
48                            ${b.hasOwnProperty("placeholder") ? "placeholder=" + b["placeholder"] : ""}
49                            ${b.hasOwnProperty("minlength") ? "minlength=" + b["minlength"] : ""}
50                            ${b.hasOwnProperty("maxlength") ? "maxlength=" + b["maxlength"] : ""}
51                        >
52                        <div class="erreur" style="display: none"></div>
53                    `
54
55                    // validation du champ
56                    champ.querySelector('input').addEventListener("input", () => {
57                        this.#validation_champ(champ)
58                    })
59
60                }
61
62                if(b['type'] == "form_radio"){
63                    champ.classList.add('form_radio')
64                
65                    //required
66                    let required = false // required par défaut
67                    if(b.hasOwnProperty("required")) required = b["required"]
68                    let required_etoile = required ? '<abbr class="requis" title="Ce champ est obligatoire">*</abbr>' : ''
69                    
70                    //options
71                    let options = ""
72                    b['options'].forEach(o => {
73                        options += `
74                            <div class="option ${o['checked'] ? 'checked' : ""}">
75                                <input
76                                    type="radio"
77                                    id="form_input_${id}-${b['id']}-${o['id']}"
78                                    name="form_input_${id}-${b['id']}"
79                                    value="${o['id']}"
80                                    ${o['checked'] ? "checked" : ""}
81                                    ${required ? "required" : ""}
82                                >
83                                <label for="form_input_${id}-${b['id']}-${o['id']}">
84                                    ${o['label']}
85                                </label>
86                            </div>
87                        `
88                    })
89
90                    champ.innerHTML = `
91                        <label class="label-principal">
92                            ${b['label']}
93                            ${required_etoile}
94                        </label>
95                        <div class="options">
96                            ${options}
97                        </div>
98                        <div class="erreur" style="display: none"></div>
99                    `
100                    champ.querySelectorAll('.form_radio .options .option').forEach(o => {
101                        o.addEventListener('change', () => {
102                            if(champ.querySelector('.form_radio .options .option.checked') != undefined) champ.querySelector('.form_radio .options .option.checked').classList.remove('checked')
103                            o.classList.add('checked')
104                            champ.querySelector('div.erreur').style.display = "none"
105                        })
106                        o.addEventListener('click', e => {
107                            if(o.classList.contains("checked")){
108                                e.preventDefault()
109                                o.classList.remove("checked")
110                                o.querySelector('input').checked = false
111                            }
112                            this.#validation_champ(champ)
113                        })
114                    })
115                }
116                
117                if(b['type'] == "form_select"){
118                    champ.classList.add('form_select')
119                
120                    //required
121                    let required = false // required par défaut
122                    if(b.hasOwnProperty("required")) required = b["required"]
123                    let required_etoile = required ? '<abbr class="requis" title="Ce champ est obligatoire">*</abbr>' : ''
124                    
125                    //options
126
127                    function creer_option(o){
128                        return `
129                            <option
130                                value="${o.id}"
131                                ${o.disabled ? "disabled" : ""}
132                                ${o.selected ? "selected" : ""}
133                            >${o.label}</option>
134                        `
135                    }
136
137                    let options = `<option value="">${b.hasOwnProperty('optionNeutre') ? b['optionNeutre'] : " -- Sélectionnez une option -- "}</option>`
138                    let position = 0
139                    b['optgroups'].sort((a, b) => a.position - b.position)
140                    b['options'].sort((a, b) => a.position - b.position)
141                    b['optgroups'].forEach(optgroup => {
142                        b['options'].forEach(o => {
143                            if(o.position < optgroup.position && o.optgroup === undefined){
144                                options += creer_option(o)
145                            }
146                        })
147                        options += `<optgroup
148                            label="${optgroup.label}"
149                            ${optgroup.disabled ? "disabled" : ""}
150                        >`
151                        b['options'].forEach(o => {
152                            if(o.optgroup == optgroup.label){
153                                options += creer_option(o)
154                            }
155                        })
156                        options += `</optgroup>`
157                        position = optgroup.position
158                    })
159                    b['options'].forEach(o => {
160                        if(o.optgroup === undefined && position < o.position){
161                            options += creer_option(o)
162                        }
163                    })
164
165                    champ.innerHTML = `
166                        <label
167                            class="label-principal"
168                            for="form_input_${id}-${b['id']}"
169                        >
170                            ${b['label']}
171                            ${required_etoile}
172                        </label>
173                        <select
174                            id="form_input_${id}-${b['id']}"
175                            name="form_input_${id}-${b['id']}"
176                            ${b["required"] ? "required" : ""}
177                        >
178                            ${options}
179                        </select>
180                        <div class="erreur" style="display: none"></div>
181                    `
182                    champ.querySelector('select').addEventListener("input", () => {
183                        this.#validation_champ(champ)
184                    })
185                }
186
187                if(b['type'] == "form_bouton"){
188                    champ.classList.add('form_bouton')
189                    let bouton = document.createElement('button');
190                    bouton.innerHTML = b['label'];
191                    bouton.addEventListener('click', e => {
192                        e.preventDefault()
193                        this.soumettreFormulaire()
194                    })
195                    champ.insertBefore(bouton, null);
196                }
197                this.form.insertBefore(champ, null)
198            })
199
200            // message resultat à la fin du formulaire, succès ou erreur
201            let msgResultat = document.createElement('div')
202            msgResultat.classList.add('msg-resultat')
203            msgResultat.style.display = "none"
204            this.form.appendChild(msgResultat)
205
206            parent.appendChild(this.form)
207        })
208        
209    }
210
211    /**
212     * Vérifie si tous les champs requis sont remplis
213     * @return {Boolean}
214     */
215
216    verifierChamps() {
217        let estValide = true;
218        // itérer à travers tous les champs de formulaire
219        this.form.querySelectorAll('.champ').forEach(champ => {
220            if(!this.#validation_champ(champ)){
221                estValide = false
222            }
223        });
224        return estValide;
225    }
226
227    soumettreFormulaire() {
228        this.premiere_soumission = false
229        if (this.verifierChamps()) {
230            let formData = new FormData(this.form);
231            formData.append('action', 'envoyer')
232            formData.append('id', this.id)
233            console.log(JSON.stringify(Object.fromEntries(formData)))
234            fetch("/script/page/formulaire.php", {
235                method: "POST",
236                headers: {
237                    'Content-Type': 'application/json',
238                },
239                body: JSON.stringify(Object.fromEntries(formData))
240            }).then(reponse => reponse.json()).then(reponse => {
241                console.log(reponse)
242                let msgResultat = this.form.querySelector('.msg-resultat')
243                if(reponse.erreur){
244                    msgResultat.innerHTML = "Une erreur est survenue. Si elle perciste contactez l'administrateur. Code d'erreur : \"" + reponse.erreurMsg + "\""
245                    msgResultat.style.display = "block"
246                    msgResultat.classList.add('erreur')
247                } else {
248                    let msg = "Vos informations ont été enregistrées avec succès. Nous vous remercions."
249                    let afficherFormulaire = false
250                    if(this.sructForm.hasOwnProperty('succes')){
251                        if(this.sructForm['succes'].hasOwnProperty('msg')) msg = this.sructForm['succes']['msg']
252                        if(this.sructForm['succes'].hasOwnProperty('msg')) msg = this.sructForm['succes']['msg']
253                    }
254                    msgResultat.innerHTML = msg
255                    msgResultat.style.display = "block"
256                    msgResultat.classList.add('succes')
257                    if(!afficherFormulaire) this.form.querySelectorAll('.champ').forEach(c => c.style.display = "none")
258                }
259            })
260                // .catch((error) => {
261                // // gérez les erreurs
262                // });
263        }
264    }
265
266    async #charger(id){
267        return fetch("/script/page/formulaire.php",{
268            method: 'POST',
269            headers: {
270                'Content-Type': 'application/json',
271            },
272            body: JSON.stringify({
273                "action": "charger",
274                "id": id
275            })
276        }).then((reponse) => {
277            return reponse.json()
278        }).then(reponse => {
279            return reponse
280        })
281    }
282    
283
284    #validation_champ(champ){
285        if(champ.classList.contains('form_texte')
286            || champ.classList.contains('form_email')
287            || champ.classList.contains('form_select')
288        ){
289            let input = champ.querySelector('input')
290            if(champ.classList.contains('form_select')) input = champ.querySelector('select')
291            let erreur = champ.querySelector('div.erreur')
292            
293            if(!this.premiere_soumission){
294                input.classList.add('erreur')
295                erreur.style.display = "block";
296            }
297            
298            // required
299            if (input.validity.valueMissing) {
300                erreur.innerHTML = "Ce champ doit être complété."
301                return false
302            }
303            
304            // minlength
305            if (input.validity.tooShort){
306                erreur.innerHTML = "Ce champ doit contenir au minimum " + input.getAttribute("minlength") + " caractères."
307                return false
308            }
309
310            // maxlength inutile html le bloc déjà
311
312            // typeMismatch (pattern)
313            if (input.validity.typeMismatch){
314                if(champ.classList.contains('form_email')){
315                    erreur.innerHTML = "Ce champ ne contient pas une adresse mail valide."
316                }else{
317                    //faire la gestion ici pour le pattern des champs texte une fois implémenté
318                    erreur.innerHTML = "Une erreur impossible est survenue, contactez l'administrateur."
319                }
320                
321                return false
322            }
323
324            // si jamais pour une raison wtf l'erreur a pas été gérée avant
325            if (!input.validity.valid){
326                erreur.innerHTML = "Ce champ comporte une erreur."
327                return false
328            }
329
330            // s'il y a pas de problème
331            input.classList.remove('erreur')
332            erreur.style.display = "none";
333        }
334        if(champ.classList.contains('form_radio')){
335            let erreur = champ.querySelector('div.erreur')
336            let radioBtn = champ.querySelectorAll('input')
337            let estCoche = false;
338            for (let i = 0; i < radioBtn.length; i++) {
339                if (radioBtn[i].checked) {
340                    estCoche = true;
341                    break;
342                }
343            }
344
345            if(radioBtn[0].hasAttribute("required")){
346                if(!estCoche){
347                    erreur.innerHTML = "Vous devez sélectionner au moins un choix."
348                    if(!this.premiere_soumission){
349                        erreur.style.display = "block";
350                    }
351                    return false
352                }
353            }
354        }
355        return true
356    }
357}
358
359document.querySelectorAll('.contenu .bloc').forEach(b => {
360    if(b.innerHTML.split('-')[0] == "formulaire"){
361        let id = b.innerHTML.split('-')[1]
362        b.innerHTML = ""
363        new Formulaire(id,b)
364    }
365})

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.