From e76b0dcb1348eb1273e8225d290d2a48a30eb6cb Mon Sep 17 00:00:00 2001 From: galenskap <jean.deborah@gmail.com> Date: Tue, 1 Apr 2025 10:32:54 +0200 Subject: [PATCH] Send contact form via an ajax call instead of directly redirecting to the php script --- .../partials/components/contact-form.njk | 77 ++++++++- src/form/contact-form-handler.php | 160 +++++++++--------- 2 files changed, 157 insertions(+), 80 deletions(-) diff --git a/src/_includes/partials/components/contact-form.njk b/src/_includes/partials/components/contact-form.njk index 1a6fc1b..422f22b 100644 --- a/src/_includes/partials/components/contact-form.njk +++ b/src/_includes/partials/components/contact-form.njk @@ -10,7 +10,10 @@ {% elif contactTitle %} <h2 id="contact-form" class="[ contact-heading ]">{{ contactTitle }}</h2> {% endif %} - <form name="contact" method="POST" action="/form/contact-form-handler.php"> + + <div class="form-messages" aria-live="polite"></div> + + <form name="contact" method="POST" action="/form/contact-form-handler.php" class="contact-form"> <ol class="[ field-list ]"> <li class="[ field-list__field-group ]"> {{ label("Nom", "namezzz") }} @@ -30,7 +33,7 @@ {% else %} {{ select( "select", [ {label: "Obtenir un rendez-vous (décrivez votre projet en quelques lignes)", value: "option 1"}, - {label: "Obtenir des précisions sur le statut d’entrepreneur salarié", value: "option 2"}, + {label: "Obtenir des précisions sur le statut d'entrepreneur salarié", value: "option 2"}, {label: "Proposer une mission à un coopérateur", value: "option 3"}, {label: "Proposer un partenariat", value: "option 4"} ], { required: true, options_before: [""], options_after: ["Autre demande"] } ) }} @@ -44,7 +47,7 @@ {{ hidden_field('subscribe', '') }} {% else %} <li class="[ field-list__field-group ] [ full-width ]"> - {{ checkboxes("", "subscribe", [ "Je souhaite être tenu au courant de l’actualité Astrolabe"], { description: "" } ) }} + {{ checkboxes("", "subscribe", [ "Je souhaite être tenu au courant de l'actualité Astrolabe"], { description: "" } ) }} </li> {% endif %} <!-- H o n e y p o t --> @@ -67,3 +70,71 @@ </form> </div> </section> + +<style> +.form-messages { + margin-bottom: 1rem; +} + +.form-messages .error { + color: #dc3545; + margin-bottom: 0.5rem; +} + +.form-messages .success { + color: #28a745; +} + +.field-error { + color: #dc3545; + font-size: 0.875rem; + margin-top: 0.25rem; +} +</style> + +<script> +document.addEventListener('DOMContentLoaded', function() { + const form = document.querySelector('.contact-form'); + const messagesContainer = document.querySelector('.form-messages'); + + form.addEventListener('submit', async function(e) { + e.preventDefault(); + + // Clean previous messages + messagesContainer.innerHTML = ''; + + // Get form data + const formData = new FormData(form); + + try { + const response = await fetch(form.action, { + method: 'POST', + body: formData + }); + + const data = await response.json(); + + if (data.success) { + // Display success message + messagesContainer.innerHTML = `<div class="success">${data.message}</div>`; + form.reset(); + // Redirect to thank you page + window.location.href = '/thank-you/index.html'; + } else { + // Display errors + const errorHtml = data.errors.map(error => + `<div class="error">${error}</div>` + ).join(''); + messagesContainer.innerHTML = errorHtml; + + // Scroll to error messages + messagesContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + } + } catch (error) { + messagesContainer.innerHTML = ` + <div class="error">Une erreur est survenue lors de l'envoi du formulaire. Veuillez réessayer.</div> + `; + } + }); +}); +</script> diff --git a/src/form/contact-form-handler.php b/src/form/contact-form-handler.php index 0a93287..5679059 100644 --- a/src/form/contact-form-handler.php +++ b/src/form/contact-form-handler.php @@ -3,9 +3,12 @@ require("/usr/share/php/libphp-phpmailer/autoload.php"); use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; +// Set header to return JSON +header('Content-Type: application/json'); + $mail = new PHPMailer(true); -$errors = ''; +$errors = []; $myEmail = getenv('ASTRO_SMTP_FROM'); $myEmailSplitted = explode('@', $myEmail); $domainFromMyEmail = ( @@ -27,11 +30,11 @@ $hcaptchaSecret = getenv('HCAPTCHA_SECRET_KEY'); $hcaptchaVerifyUrl = "https://api.hcaptcha.com/siteverify"; if(empty($_POST['namezzz']) || empty($_POST['emailzzz']) || empty($_POST['message'])) { - $errors .= "\n Erreur : champs obligatoires manquants."; + $errors[] = "Erreur : champs obligatoires manquants."; } if(!empty($_POST['name']) && !empty($_POST['email'])) { - $errors .= "\n Erreur : spam détecté."; + $errors[] = "Erreur : spam détecté."; } /* Captcha verification */ @@ -53,10 +56,10 @@ if(!empty($_POST['h-captcha-response'])) { $responseData = json_decode($response, true); if(!$responseData['success']) { - $errors .= "\n Erreur lors de la validation du captcha."; + $errors[] = "Erreur lors de la validation du captcha."; } } else { - $errors .= "\n Erreur lors de la validation du captcha."; + $errors[] = "Erreur lors de la validation du captcha."; } $name = $_POST['namezzz']; @@ -66,81 +69,84 @@ $message = $_POST['message']; $subscribe = $_POST['subscribe']; if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) { - $errors .= "\n Erreur d'adresse e-mail invalide : $emailAddress"; + $errors[] = "Erreur d'adresse e-mail invalide : $emailAddress"; } if(empty($errors)) { - $emailSubject = "[Formulaire Astrolabe] Nouveau message"; + try { + $emailSubject = "[Formulaire Astrolabe] Nouveau message"; - switch ($select) { - case "option 1": - $purpose = "Demande de rendez-vous"; - break; - case "option 2": - $purpose = "Demande de précisions sur le statut d’entrepreneur salarié"; - break; - case "option 3": - $purpose = "Proposition de misson"; - break; - case "option 4": - $purpose = "Proposition de partenariat"; - break; - default: - $purpose = "Autre demande"; + switch ($select) { + case "option 1": + $purpose = "Demande de rendez-vous"; + break; + case "option 2": + $purpose = "Demande de précisions sur le statut d'entrepreneur salarié"; + break; + case "option 3": + $purpose = "Proposition de misson"; + break; + case "option 4": + $purpose = "Proposition de partenariat"; + break; + default: + $purpose = "Autre demande"; + } + $emailSubject .= " : $purpose"; + + $emailBody = "Vous avez reçu un nouveau message depuis le formulaire du site Astrolabe :". + "\r\n\r\nNom: $name \r\nEmail: $emailAddress \r\nRaison: $purpose\r\nSubscribe: $subscribe\r\n\r\n$message"; + + $emailBodyHTML = str_replace("\r\n", "<br>", $emailBody); + + $mail->isSMTP(); + $mail->Host = getenv('ASTRO_SMTP_HOSTNAME'); + $mail->SMTPAuth = true; + $mail->Username = getenv('ASTRO_SMTP_USERNAME'); + $mail->Password = getenv('ASTRO_SMTP_PASSWORD'); + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = 587; + + //Options + $mail->CharSet = 'UTF-8'; + $mail->WordWrap = 70; + + //Recipients + $mail->setFrom($myEmail); + $mail->addAddress($wantedContact); + $mail->addReplyTo($emailAddress, $name); + + // Content + $mail->isHTML(true); + $mail->Subject = $emailSubject; + $mail->Body = $emailBodyHTML; + $mail->AltBody = $emailBody; + + $mail->send(); + + // if subscribe add to mailing list + if(!empty($subscribe)) { + // process + // enovoi mail add to mailing list + } + + http_response_code(200); + echo json_encode([ + 'success' => true, + 'message' => 'Message envoyé avec succès' + ]); + + } catch (Exception $e) { + http_response_code(500); + echo json_encode([ + 'success' => false, + 'errors' => ["Erreur lors de l'envoi du message : " . $mail->ErrorInfo] + ]); } - $emailSubject .= " : $purpose"; - - $emailBody = "Vous avez reçu un nouveau message depuis le formulaire du site Astrolabe :". - "\r\n\r\nNom: $name \r\nEmail: $emailAddress \r\nRaison: $purpose\r\nSubscribe: $subscribe\r\n\r\n$message"; - - $emailBodyHTML = str_replace("\r\n", "<br>", $emailBody); - - $mail->isSMTP(); - $mail->Host = getenv('ASTRO_SMTP_HOSTNAME'); - $mail->SMTPAuth = true; - $mail->Username = getenv('ASTRO_SMTP_USERNAME'); - $mail->Password = getenv('ASTRO_SMTP_PASSWORD'); - $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; - $mail->Port = 587; - - //Options - $mail->CharSet = 'UTF-8'; - $mail->WordWrap = 70; - - //Recipients - $mail->setFrom($myEmail); - $mail->addAddress($wantedContact); - $mail->addReplyTo($emailAddress, $name); - - // Content - $mail->isHTML(true); - $mail->Subject = $emailSubject; - $mail->Body = $emailBodyHTML; - $mail->AltBody = $emailBody; - - $mail->send(); - - // if subscribe add to mailing list - if(!empty($subscribe)) { - // process - // enovoi mail add to mailing list - } - - // redirect to the 'thank you' page - header("Location: /thank-you/index.html"); +} else { + http_response_code(400); + echo json_encode([ + 'success' => false, + 'errors' => $errors + ]); } -?> -<!DOCTYPE html> -<html> - <head> - <title>Contact form handler</title> - </head> - - <body> - <!-- This page is displayed only if there is some error --> - <?php - echo nl2br($errors); - ?> - <a href="javascript:history.back()">Retour</a> - </body> -</html>