Chapitre 16 – Mini-projet : Formulaire AJAX complet
Ce dernier chapitre est un mini-projet complet qui réunit tout ce que tu as appris : sélection, événements, validation, UX, AJAX, gestion des erreurs et bonnes pratiques. L’objectif est de construire un formulaire réaliste, robuste et professionnel.
1) Objectif du mini-projet
- Construire un formulaire d’inscription (pseudo, email, mot de passe)
- Valider côté client (UX) avant l’envoi
- Envoyer en AJAX (sans recharger la page)
- Gérer l’état “chargement” et les erreurs serveur
- Structurer le code (fonctions réutilisables)
Pour t’entraîner, tu peux d’abord faire fonctionner le projet “en simulation” (sans serveur),
puis brancher une vraie API (PHP/Node) ensuite.
2) Structure HTML recommandée
On place un petit bloc d’erreur sous chaque champ. On prévoit aussi une zone de message global.
<form id="registerForm">
<label>Pseudo</label>
<input type="text" name="username" id="username" autocomplete="username">
<div class="field-error"></div>
<label>Email</label>
<input type="email" name="email" id="email" autocomplete="email">
<div class="field-error"></div>
<label>Mot de passe</label>
<input type="password" name="password" id="password" autocomplete="new-password">
<div class="field-error"></div>
<button type="submit" id="submitBtn">S'inscrire</button>
</form>
<p id="message"></p>
Important : chaque champ doit avoir un name, sinon serialize() ne l’enverra pas.
3) Rappels : fonctions utilitaires (validation + UI)
Validation email (simple)
function isValidEmail(email){
// Validation simple côté client (la validation stricte doit être côté serveur)
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
Gestion des erreurs par champ
function showError($field, message){
$field.addClass('has-error');
$field.next('.field-error').text(message);
}
function clearError($field){
$field.removeClass('has-error');
$field.next('.field-error').text('');
}
État “chargement”
function setLoading($btn, loading){
$btn.prop('disabled', loading);
$btn.text(loading ? 'Envoi...' : "S'inscrire");
}
4) Script jQuery complet (validation + AJAX + UX)
Ce script :
- bloque le submit (pas de reload)
- valide les champs
- envoie en AJAX si OK
- affiche un message succès/erreur
- gère loading (bouton désactivé)
$(function(){
function isValidEmail(email){
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function showError($field, message){
$field.addClass('has-error');
$field.next('.field-error').text(message);
}
function clearError($field){
$field.removeClass('has-error');
$field.next('.field-error').text('');
}
function setLoading($btn, loading){
$btn.prop('disabled', loading);
$btn.text(loading ? 'Envoi...' : "S'inscrire");
}
$('#registerForm').on('submit', function(e){
e.preventDefault();
// Cache (lecture des champs)
const $form = $(this);
const $username = $('#username');
const $email = $('#email');
const $password = $('#password');
const $btn = $('#submitBtn');
const $message = $('#message');
// Reset UI
clearError($username);
clearError($email);
clearError($password);
$message.text('');
// Récupération + nettoyage
const username = String($username.val()).trim();
const email = String($email.val()).trim();
const password = String($password.val()).trim();
// Validation
let ok = true;
if(username.length < 3){
showError($username, 'Pseudo trop court (min 3 caractères).');
ok = false;
}
if(!email){
showError($email, 'Email requis.');
ok = false;
} else if(!isValidEmail(email)){
showError($email, 'Format email invalide.');
ok = false;
}
if(password.length < 6){
showError($password, 'Mot de passe trop court (min 6).');
ok = false;
}
if(!ok){
$message.text('Merci de corriger le formulaire.');
return;
}
// Envoi AJAX
setLoading($btn, true);
$message.text('Envoi en cours...');
$.ajax({
url: 'api/register.php', // à adapter (PHP/Node/etc.)
method: 'POST',
data: $form.serialize(),
dataType: 'json' // attendu : JSON
})
.done(function(resp){
// Exemple de réponse attendue : { ok:true, message:"..." }
if(resp && resp.ok){
$message.text(resp.message || 'Inscription réussie !');
// Optionnel : reset formulaire
$form[0].reset();
} else {
$message.text((resp && resp.message) ? resp.message : 'Échec de l’inscription.');
}
})
.fail(function(xhr){
// Ici on ne révèle pas de détails techniques à l'utilisateur
$message.text('Erreur serveur ou réseau. Réessaye plus tard.');
console.error('AJAX', xhr.status, xhr.statusText);
})
.always(function(){
setLoading($btn, false);
});
});
});
Attention : dataType: 'json' exige que ton API renvoie du JSON valide.
Si ton serveur renvoie du HTML, la requête passera en fail.
5) Exemple de réponse JSON côté serveur
Ton serveur devrait renvoyer quelque chose de ce style :
{
"ok": true,
"message": "Compte créé avec succès."
}
En cas d’erreur :
{
"ok": false,
"message": "Cet email est déjà utilisé."
}
6) Améliorations possibles (niveau “portfolio”)
- Validation “en direct” (sur blur) après le premier submit
- Force du mot de passe (barre de progression)
- Affichage d’un toast (succès/erreur) au lieu d’un simple paragraphe
- Réponse serveur plus riche : codes d’erreur, champs en erreur, etc.
- Protection anti-spam (captcha côté serveur si besoin)
Exercice (final) – Le rendre “réel” avec une API
- Crée un endpoint api/register.php (ou Node) qui reçoit POST.
- Valide côté serveur (obligatoire).
- Retourne du JSON avec ok et message.
- Teste : succès, email déjà pris, champs manquants, erreur serveur.
Résumé du chapitre
- On intercepte le submit, puis on valide
- On affiche des erreurs par champ (UX)
- On envoie en AJAX (serialize)
- On gère loading, succès, erreur, always()
- On attend du JSON côté serveur