Skip to content

Latest commit

 

History

History
204 lines (179 loc) · 7.75 KB

build-forms.mdx

File metadata and controls

204 lines (179 loc) · 7.75 KB
title description i18nReady type
Créer des formulaires HTML dans Astro Pages
Apprenez à construire des formulaires HTML et à gérer les soumissions dans votre frontmatter.
true
recipe

En mode SSR, les pages Astro peuvent à la fois afficher et gérer des formulaires. Dans cette recette, vous utiliserez un formulaire HTML standard pour soumettre des données au serveur. Votre script frontmatter traitera les données sur le serveur, sans envoyer de JavaScript au client.

Prérequis

  • Un projet avec SSR (output: 'server') activé

Recette

  1. Créez ou identifiez une page .astro qui contiendra votre formulaire et votre code de manipulation. Par exemple, vous pouvez ajouter une page d'enregistrement :

    ---
    ---
    <h1>S'enregistrer</h1>
  2. Ajoutez une balise <form> avec quelques entrées à la page. Chaque entrée doit avoir un attribut name qui décrit la valeur de cette entrée.

    Veillez à inclure un élément <button> ou <input type="submit"> pour soumettre le formulaire.

    ---
    ---
    <h1>S'enregistrer</h1>
    <form>
      <label>
        Nom d'utilisateur :
        <input type="text" name="username" />
      </label>
      <label>
        Email :
        <input type="email" name="email" />
      </label>
      <label>
        Mot de passe :
        <input type="password" name="password" />
      </label>
      <button>Soumettre</button>
    </form>
  3. Utilisez la Validation des données de formulaires pour fournir une validation de base côté client qui fonctionne même si JavaScript est désactivé.

    Dans cet exemple,

    • required empêche la soumission du formulaire tant que le champ n'est pas rempli.
    • minlength fixe une longueur minimale requise pour le texte saisi.
    • type="email" introduit également une validation qui n'acceptera qu'un format d'email valide.
    ---
    ---
    <h1>S'enregistrer</h1>
    <form>
      <label>
        Nom d'utilisateur :
        <input type="text" name="username" required />
      </label>
      <label>
        Email :
        <input type="email" name="email" required />
      </label>
      <label>
        Mot de passe:
        <input type="password" name="password" required minlength="6" />
      </label>
      <button>Soumettre</button>
    </form>

    :::tip Vous pouvez ajouter une logique de validation personnalisée qui fait référence à plusieurs champs en utilisant une balise <script> et l'API d'implémentation des contraintes complexes.

    Pour écrire une logique de validation complexe plus facilement, vous pouvez construire votre formulaire en utilisant un Framework frontend et choisir une bibliothèque de formulaire comme React Hook Form ou Felte. :::

  4. La soumission du formulaire amènera le navigateur à redemander la page. Changez la méthode de transfert de données du formulaire en POST pour envoyer les données du formulaire en tant que partie du corps de la Request, plutôt qu'en tant que paramètres d'URL.

    ---
    ---
    <h1>S'enregistrer</h1>
    <form method="POST">
      <label>
        Nom d'utilisateur:
        <input type="text" name="username" required />
      </label>
      <label>
        Email:
        <input type="email" name="email" required />
      </label>
      <label>
        Mot de passe:
        <input type="password" name="password" required minlength="6" />
      </label>
      <button>Soumettre</button>
    </form>
  5. Vérifier la méthode POST dans le frontmatter et accéder aux données du formulaire en utilisant Astro.request.formData(). Enveloppez ceci dans un bloc try ... catch pour gérer les cas où la requête POST n'a pas été envoyée par un formulaire et où les formData ne sont pas valides.

    ---
    if (Astro.request.method === "POST") {
      try {
        const data = await Astro.request.formData();
        const name = data.get("username");
        const email = data.get("email");
        const password = data.get("password");
        // Faire quelque chose avec les données
      } catch (error) {
        if (error instanceof Error) {
          console.error(error.message);
        }
      }
    }
    ---
    <h1>S'enregistrer</h1>
    <form method="POST">
      <label>
        Nom d'utilisateur:
        <input type="text" name="username" required />
      </label>
      <label>
        Email :
        <input type="email" name="email" required />
      </label>
      <label>
        Mot de passe :
        <input type="password" name="password" required minlength="6" />
      </label>
      <button>Soumettre</button>
    </form>
  6. Validez les données du formulaire sur le serveur. Cette validation doit être la même que celle effectuée sur le client afin d'éviter les soumissions malveillantes à votre point d'accès et de prendre en charge les rares navigateurs anciens qui ne disposent pas de la validation des formulaires.

    Elle peut également inclure la validation qui ne peut pas être effectuée sur le client. Par exemple, cet exemple vérifie si l'email est déjà dans la base de données.

    Les messages d'erreur peuvent être renvoyés au client en les stockant dans un objet errors et en y accédant dans le modèle.

    ---
    import { isRegistered, registerUser } from "../../data/users"
    import { isValidEmail } from "../../utils/isValidEmail";
    
    const errors = { username: "", email: "", password: "" };
    if (Astro.request.method === "POST") {
      try {
        const data = await Astro.request.formData();
        const name = data.get("username");
        const email = data.get("email");
        const password = data.get("password");
        if (typeof name !== "string" || name.length < 1) {
          errors.username += "Veuillez saisir un nom d'utilisateur. ";
        }
        if (typeof email !== "string" || !isValidEmail(email)) {
          errors.email += "L'e-mail n'est pas valide. ";
        } else if (await isRegistered(email)) {
          errors.email += "L'email est déjà enregistré. ";
        }
        if (typeof password !== "string" || password.length < 6) {
          errors.password += "Le mot de passe doit comporter au moins 6 caractères. ";
        }
        const hasErrors = Object.values(errors).some(msg => msg)
        if (!hasErrors) {
          await registerUser({name, email, password});
          return Astro.redirect("/login");
        }
      } catch (error) {
        if (error instanceof Error) {
          console.error(error.message);
        }
      }
    }
    ---
    <h1>S'enregistrer</h1>
    <form method="POST">
      <label>
        Nom d'utilisateur :
        <input type="text" name="username" />
      </label>
      {errors.username && <p>{errors.username}</p>}
      <label>
        Email :
        <input type="email" name="email" required />
      </label>
      {errors.email && <p>{errors.email}</p>}
      <label>
        Mot de passe :
        <input type="password" name="password" required minlength="6" />
      </label>
      {errors.password && <p>{errors.password}</p>}
      <button>Valider</button>
    </form>