Skip to content

Formulaire de contact

Introduction

Le formulaire de contact est un élément essentiel dans un site web, permettant aux utilisateurs de communiquer facilement avec le propriétaire du site. Dans ce chapitre, nous allons explorer en détail la mise en place d'un formulaire de contact fonctionnel, en utilisant HTML, JavaScript et PHP. Nous allons examiner la structure HTML du formulaire, la validation des données côté client et côté serveur, ainsi que l'envoi des données par email.

Structure HTML du formulaire

Voici la structure HTML du formulaire de contact :

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Contact</title>
    <style>
      .error-message {
        color: red;
      }

      form > div {
        margin-bottom: 1rem;
      }
    </style>
  </head>
  <body>
    <h1>Contact</h1>
    <form>
      <div>
        <label for="nom">Nom</label>
        <input id="nom" name="nom" />
        <div id="error-nom" class="error-message"></div>
      </div>
      <div>
        <label for="sujet">Sujet</label>
        <input id="sujet" name="sujet" />
        <div id="error-sujet" class="error-message"></div>
      </div>
      <div>
        <label for="email">Email</label>
        <input name="email" type="email" />
        <div id="error-email" class="error-message"></div>
      </div>
      <div>
        <label for="message">Message</label>
        <textarea name="message"></textarea>
        <div id="error-message" class="error-message"></div>
      </div>
      <script
        src="./captcha/script.js?version=17"
        countdown="on"
        label="Captcha"
        enemies="4"
      ></script>
      <div id="error-captcha" class="error-message"></div>
      <button>Envoyer</button>
    </form>
    <script>
      // Code JavaScript pour la gestion du formulaire
    </script>
  </body>
</html>

Le formulaire est composé de plusieurs champs tels que le nom, le sujet, l'email et le message. Chaque champ est enveloppé dans une balise <div> pour faciliter la mise en forme et la gestion des erreurs. Les messages d'erreur sont affichés à côté de chaque champ à l'aide de la classe CSS .error-message.

Validation des données côté client en JavaScript

Nous allons maintenant ajouter du code JavaScript pour valider les données saisies par l'utilisateur avant l'envoi du formulaire. Voici le code correspondant :

js
<script>
  const form = document.querySelector("form");
  form.addEventListener("submit", (event) => {
    removeErrors();
    event.preventDefault();

    if (!captcha_done) {
      const errorSpan = document.querySelector("#error-captcha");
      errorSpan.textContent =
        "Veuillez valider le captcha avant d'envoyer le formulaire";
      return;
    }

    const formData = new FormData(form);
    fetch("./contact.php", {
      method: "POST",
      body: formData,
    })
      .then((response) => {
        console.log(response);
        // si le code de statut est 422
        if (response.status === 422) {
          response.json().then((errors) => {
            console.log(errors);
            displayErrors(errors.erreurs);
          });
        } else if (response.status === 200) {
          // afficher un message de succès
          console.log("success");
        }
      })
      .catch((error) => {
        console.error(error);
      });
  });

  function displayErrors(errors) {
    for (const key in errors) {
      const errorSpan = document.querySelector(`#error-${key}`);
      errorSpan.textContent = errors[key];
    }
  }

  function removeErrors() {
    const errorSpans = document.querySelectorAll(".error-message");
    errorSpans.forEach((errorSpan) => {
      errorSpan.textContent = "";
    });
  }
</script>

Ce code ajoute un écouteur d'événement sur l'événement "submit" du formulaire. Lorsque l'utilisateur soumet le formulaire, le code est exécuté. Nous commençons par supprimer tous les messages d'erreur précédents à l'aide de la fonction removeErrors(). Ensuite, nous vérifions si le captcha a été validé. Si le captcha n'a pas été validé, un message d'erreur est affiché et le formulaire n'est pas envoyé. Si le captcha est valide, nous récupérons les données du formulaire à l'aide de l'objet FormData et nous les envoyons au fichier PHP contact.php à l'aide de la fonction fetch(). En fonction de la réponse du serveur, nous affichons les messages d'erreur appropriés ou un message de succès.

Validation des données côté serveur en PHP

Le fichier contact.php est responsable de la validation des données du formulaire côté serveur. Voici le code correspondant :

php
<?php

$erreurs = validerDonnees();

// on indique que le contenu est du json
header('Content-type: application/json');

// si il y a des erreurs, on les renvois au client
if (count($erreurs) > 0) {
    // on encode les erreurs en json
    $erreurs = json_encode(['erreurs' => $erreurs]);
    // on renvois un code d'erreur 422 (Unprocessable Entity)
    http_response_code(422);
    echo $erreurs;
} else {
    // si il n'y a pas d'erreurs, on envois le mail
    envoyerMail();
    // on renvois un code 200 (OK)
    echo json_encode(['message' => 'Votre message a bien été envoyé.']);
}

// on arrête le script
exit;

function validerDonnees()
{
    $nom = sanitize($_POST['nom'] ?? null);
    $email = sanitize($_POST['email'] ?? null);
    $sujet = sanitize($_POST['sujet'] ?? null);
    $message = sanitize($_POST['message'] ?? null);

    $erreurs = [];
    $erreurs['nom'] = obligatoire($nom, 'nom');
    $erreurs['sujet'] = obligatoire($sujet, 'sujet');
    $erreurs['email'] = emailValide($email, 'email');
    $erreurs['message'] = obligatoire($message, 'message');

    // on supprime les erreurs vides
    $erreurs = array_filter($erreurs);

    return $erreurs;
}

function obligatoire($valeur, $nomDuChamps)
{
    if (is_null($valeur) || '' === trim($valeur)) {
        return "Le champs {$nomDuChamps} est obligatoire";
    }
}

function emailValide($valeur, $nomDuChamps)
{
    $erreur = obligatoire($valeur, 'email');
    if (null !== $erreur) {
        return $erreur;
    }

    if (!filter_var($valeur, FILTER_VALIDATE_EMAIL)) {
        return "Le champs {$nomDuChamps} n'est pas une adresse email valide";
    }
}

function envoyerMail()
{
    $nomSite = sanitize('Mon site');
    $nom = sanitize($_POST['nom']);
    $email = sanitize($_POST['email']);
    $sujet = sanitize($_POST['sujet']);
    $message = sanitize($_POST['message']);

    $from = 'test@example.com';
    $to = 'test@example.com';

    mail(
        $to,
        "[{$nomSite}] Prise de contact de {$nom}.",
        <<<EOT
            Nom : {$nom}
            Email : {$email}
            Sujet : {$sujet}

            Message :
            {$message}
        EOT,
        [
            'From' => $from,
            'Reply-To' => $email,
        ]
    );
}

function sanitize($valeur)
{
    // on supprime les espaces en début et fin de chaîne
    // et on convertit les caractères spéciaux en entités html
    // pour éviter les failles XSS
    return htmlspecialchars(trim($valeur ?? ''));
}

Ce code commence par appeler la fonction validerDonnees() pour valider les données du formulaire. Si des erreurs sont détectées, elles sont renvoyées au client sous forme de réponse JSON avec le code d'erreur 422. Sinon, le code appelle la fonction envoyerMail() pour envoyer les données du formulaire par email et renvoie un message de succès au client avec le code 200.

Code sur GitHub