Formulaire multi-pages / validation des champs

Résolu
PJ47 Messages postés 77 Date d'inscription jeudi 2 mars 2023 Statut Membre Dernière intervention 27 février 2024 - Modifié le 26 févr. 2024 à 16:13
PJ47 Messages postés 77 Date d'inscription jeudi 2 mars 2023 Statut Membre Dernière intervention 27 février 2024 - 27 févr. 2024 à 09:39

Bonjour,

je viens de trouver le moyen de mettre mon formulaire de contact en format "pas à pas".

le formulaire fonctionne, je reçois les mails de contacts et les données s'enregistrent très bien dans ma BDD.

Je voudrais juste que le bouton "suivant" ne puisse pas fonctionner si les champs obligatoires ne sont pas remplis.

url de test : https://www.best-termites.fr/www/contact.php

HTML : 

<div class="tout">
  <header></header>
  <form name="inscription" method="post" class="form" action="contact.php">
    <div class="page" id="page1">
      <h1>Identité</h1>
      <div class="row mb-3">
        <input
          type="text"
          name="entreprise"
          onkeyup="this.value=this.value.toUpperCase()"
          placeholder="Entreprise"
        />
      </div>
      <div class="row mb-3">
        <input
          type="text"
          name="nom"
          onkeyup="this.value=this.value.toUpperCase()"
          placeholder="Nom*"
          required
        />
      </div>

      <div class="row mb-3">
        <input
          type="text"
          name="prenom"
          onkeyup="this.value=this.value.toUpperCase()"
          placeholder="Prénom*"
          required
        />
      </div>
      <button class="next" type="button" id="button-ts">Suivant</button>
    </div>
    <div class="page" id="page2">
      <h1>Informations</h1>
      <div class="row mb-3">
        <input
          name="tel"
          type="tel"
          placeholder="Téléphone - 0000000000"
          required
          pattern="[0-9]{10}"
        />
        <span class="validity"></span>
      </div>

      <div class="row mb-3">
        <input
          type="email"
          name="mail"
          pattern="[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}$"
          placeholder="Email"
          required
        />
      </div>
      <button class="prev" type="button">Précédent</button>
      <button class="next" type="button" id="button-ts">Suivant</button>
    </div>
    <div class="page" id="page3">
      <h1>Travaux</h1>
      <div class="row mb-3">
        <select id="travaux" class="form-group" name="travaux" required>
          <option disabled selected>Votre besoin</option>
          <option>Traitement Termites</option>
          <option>Traitement Humidité</option>
          <option>Traitement Charpente</option>
          <option>Traitement Mérule</option>
        </select>
      </div>
      <button class="prev" type="button">Précédent</button>
      <button class="next" type="button" id="button-ts">Suivant</button>
    </div>

    <div class="page" id="page4">
      <h1>Lieu des Travaux</h1>
      <div class="row mb-3">
        <select id="departement" class="form-group" name="departement" required>
          <option disabled selected>Votre Département</option>
          <option>47 - Lot et Garonne</option>
          <option>46 - Lot</option>
          <option>32 - Gers</option>
        </select>
      </div>

      <div class="row mb-3">
        <input
          type="text"
          name="codepostal"
          pattern="(?:0[1-9]|[1-8]\d|9[0-8])\d{3}"
          placeholder="Code Postal d'intervention"
          required
        />
      </div>
      <div class="row mb-3">
        <input
          type="text"
          name="ville"
          onkeyup="this.value=this.value.toUpperCase()"
          placeholder="ville"
          required
        />
      </div>
      <button class="prev" type="button">Précédent</button>
      <button class="next" type="button" id="button-ts">Suivant</button>
    </div>

    <div class="page" id="page5">
      <h1>Message</h1>
      <div class="row mb-3">
        <textarea
          name="message"
          rows="10"
          cols="70"
          pattern="'#^[a-zA-Z0-9áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ\.\_\-\s]{5,500}$#'
                        "
          placeholder="Votre Message"
          required
        ></textarea>
      </div>
      <button class="prev" type="button">Précédent</button>
      <button class="next" type="button" id="button-ts">Suivant</button>
    </div>

    <div class="page" id="page6">
      <div class="form-check">
        <input
          class="form-check-input"
          type="checkbox"
          name="coche"
          value="oui"
          id="invalidCheck2"
          required
        />
        <label class="form-check-label" for="invalidCheck2">
          J'accèpte d'être recontacté pour ma demande.
        </label>
      </div>

      <div class="im">
        <input type="text" name="captcha" class="captcha" required />
        <img class="imgca"
          src="image.php"
          onclick="this.src='image.php?' + Math.random();"
          alt="captcha"
          style="cursor: pointer"
        />
      </div>
      <button class="prev" type="button">Précédent</button>
      <input style="text-align:center;" type="submit" class="button" name="valider" value="Envoyer" />
    </div>
  </form>
</div>

css : 

.tout{
 width: 80%;
    border: 1px solid lightgrey;
    padding: 20px;
    border-radius: 5px;
margin:auto;
}

input{
    display: block;
    width: 100%;
    margin-top: 5px;
    margin-bottom: 5px;
    border: 1px solid lightgrey;
    border-radius: 5px;
}

.page{
    display: none;
}

header{
    display: flex;
    justify-content: space-between;
margin:2rem;
}

.page-num{
font-size: 2rem;
    width: 50px;
    height: 50px;
    text-align: center;
    padding: 10px;
}

.active{
    color: #f88f25;
font-weight: bolder;
}

.button{
display: flex;
    background-color: #333333;
    margin: auto;
width: 30%;
    padding: 10px;
    margin-top:20px;
    color: white;
    font-size: 20px;
    border-radius: 18%;
}
.im{
display: flex;
flex-direction: row;

}
.captcha{
margin-top:20px;
 width: 40%;
}
.prev, .next{
margin-top:2rem;
}
.imgca{
margin-left:2rem;
}

javascript à la fin de mon body

<script>
  // On va chercher les différents éléments de notre page
const pages = document.querySelectorAll(".page")
const header = document.querySelector("header")
const nbPages = pages.length // Nombre de pages du formulaire
let pageActive = 1

// On attend le chargement de la page
window.onload = () => {
    // On affiche la 1ère page du formulaire
    document.querySelector(".page").style.display = "initial"

    // On affiche les numéros des pages dans l'entête
    // On parcourt la liste des pages
    pages.forEach((page, index) => {
        // On crée l'élément "numéro de page"
        let element = document.createElement("div")
        element.classList.add("page-num")
        element.id = "num" + (index + 1)
        if(pageActive === index + 1){
            element.classList.add("active")
        }
        element.innerHTML = index + 1
        header.appendChild(element)
    })

    // On gère les boutons "suivant"
    let boutons = document.querySelectorAll(".next")

    for(let bouton of boutons){
        bouton.addEventListener("click", pageSuivante)
    }

    // On gère les boutons "suivant"
    boutons = document.querySelectorAll(".prev")

    for(let bouton of boutons){
        bouton.addEventListener("click", pagePrecedente)
    }
}

/**
 * Cette fonction fait avancer le formulaire d'une page
 */
function pageSuivante(){
    // On masque toutes les pages
    for(let page of pages){
        page.style.display = "none"
    }

    // On affiche la page suivante
    this.parentElement.nextElementSibling.style.display = "initial"

    // On "désactive" la page active
    document.querySelector(".active").classList.remove("active")

    // On incrémente pageActive
    pageActive++

    // On "active" le nouveau numéro
    document.querySelector("#num"+pageActive).classList.add("active")
}

/**
 * Cette fonction fait reculer le formulaire d'une page
 */
function pagePrecedente(){
    // On masque toutes les pages
    for(let page of pages){
        page.style.display = "none"
    }

    // On affiche la page suivante
    this.parentElement.previousElementSibling.style.display = "initial"

    // On "désactive" la page active
    document.querySelector(".active").classList.remove("active")

    // On incrémente pageActive
    pageActive--

    // On "active" le nouveau numéro
    document.querySelector("#num"+pageActive).classList.add("active")
}
</script>

Merci de vos retours

J

1 réponse

PJ47 Messages postés 77 Date d'inscription jeudi 2 mars 2023 Statut Membre Dernière intervention 27 février 2024 1
27 févr. 2024 à 09:39

Bonjour @tous, 

j'ai constaté que mon dernier post à été résolu par un BOBot- Donc comme ce post n'avais pas l'air d'inspiré non plus j'ai tenté l'approche Chat GPT (version gratuite !)

il m'a, après plusieurs heures de discutions, apporté la solution suivante :

<script>
    document.addEventListener("DOMContentLoaded", function () {
        const pages = document.querySelectorAll(".page");
        const header = document.querySelector("header");
        const nbPages = pages.length;
        let pageActive = 1;

        window.onload = () => {
            const premierePage = document.querySelector(".page");
            premierePage.style.display = "initial";
            premierePage.classList.add("active");

            pages.forEach((page, index) => {
                let element = document.createElement("div");
                element.classList.add("page-num");
                element.id = "num" + (index + 1);
                if (pageActive === index + 1) {
                    element.classList.add("active");
                }
                element.innerHTML = index + 1;
                header.appendChild(element);
            });

            let boutonsSuivants = document.querySelectorAll(".next");
            let boutonsPrecedents = document.querySelectorAll(".prev");

            boutonsSuivants.forEach(bouton => {
                bouton.addEventListener("click", () => pageSuivante(bouton));
            });

            boutonsPrecedents.forEach(bouton => {
                bouton.addEventListener("click", pagePrecedente);
            });
        };




function getAllRequiredFieldsBeforePage(page) {
    const indexPage = Array.from(pages).indexOf(page);
    const champsObligatoiresPagesPrecedentes = [];

    for (let i = 0; i < indexPage; i++) {
        const champsObligatoires = pages[i].querySelectorAll("[required]");
        champsObligatoires.forEach(champ => {
            champsObligatoiresPagesPrecedentes.push(champ);
        });
    }

    return champsObligatoiresPagesPrecedentes;
}

function pageSuivante(bouton) {
    const pageCourante = document.querySelector(".page.active");
    const champsObligatoiresPageCourante = pageCourante.querySelectorAll("[required]");

    let tousChampsPageCouranteRemplis = true;

    champsObligatoiresPageCourante.forEach(champ => {
        if (champ.tagName.toLowerCase() === "select" && champ.selectedIndex === 0) {
            tousChampsPageCouranteRemplis = false;
            alert("Veuillez sélectionner une option dans la liste déroulante avant de passer à la page suivante.");
        } else if (!champ.value.trim()) {
            tousChampsPageCouranteRemplis = false;
            alert("Veuillez remplir tous les champs obligatoires avant de passer à la page suivante.");
        }
    });

    if (tousChampsPageCouranteRemplis) {
        const nouvellePage = bouton.parentElement.nextElementSibling;
        if (nouvellePage) {
            const champsObligatoiresPagesPrecedentes = getAllRequiredFieldsBeforePage(nouvellePage);
            let tousChampsPagesPrecedentesRemplis = true;

            champsObligatoiresPagesPrecedentes.forEach(champ => {
                if (champ.tagName.toLowerCase() === "select" && champ.selectedIndex === 0) {
                    tousChampsPagesPrecedentesRemplis = false;
                } else if (!champ.value.trim()) {
                    tousChampsPagesPrecedentesRemplis = false;
                }
            });

            if (tousChampsPagesPrecedentesRemplis) {
                pages.forEach(page => page.style.display = "none");
                nouvellePage.style.display = "initial";
                document.querySelector(".active").classList.remove("active");
                pageActive++;
                document.querySelector("#num" + pageActive).classList.add("active");
            } else {
                alert("Veuillez remplir tous les champs obligatoires des pages précédentes avant de passer à la page suivante.");
            }
        }
    }
}

        function pagePrecedente() {
            pages.forEach(page => page.style.display = "none");

            this.parentElement.previousElementSibling.style.display = "initial";
            document.querySelector(".active").classList.remove("active");
            pageActive--;
            document.querySelector("#num" + pageActive).classList.add("active");
        }
    });
</script>

 cela semble fonctionné correctement- vu que je n'ai pas de connaissance en javascript, je ne suis donc pas capable d'améliorer simplifier ce code si nécessaire mais cela m'apporte la solution à mon pb.

cool je résous mon pb dommage que ce soit avec un robot (il parait que c'est l'avenir !!)

je clôture donc le sujet pour ne pas encombrer .

bonne journée 

0