From 863a57595e3f2c74bfcbf5e4abd0ad23b2131ed1 Mon Sep 17 00:00:00 2001 From: Francesco Lorenzo D'Amico Date: Fri, 21 Aug 2026 15:32:54 +0200 Subject: [PATCH] Require subject and validate contact form fields before submit --- .../Controllers/Api/V1/ContactController.cs | 2 +- .../RazorPagesMovieContextModelSnapshot.cs | 1 + RazorPagesMovie/Models/ContactMessage.cs | 3 +- RazorPagesMovie/Pages/Bewerbung.cshtml | 91 +++++++++++++++---- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/RazorPagesMovie/Controllers/Api/V1/ContactController.cs b/RazorPagesMovie/Controllers/Api/V1/ContactController.cs index 50be768..3c463a7 100644 --- a/RazorPagesMovie/Controllers/Api/V1/ContactController.cs +++ b/RazorPagesMovie/Controllers/Api/V1/ContactController.cs @@ -18,7 +18,7 @@ public class ContactController(RazorPagesMovieContext context) : ControllerBase Name = request.Name ?? string.Empty, Email = request.Email ?? string.Empty, Phone = request.Phone, - Subject = request.Subject, + Subject = request.Subject ?? string.Empty, Message = request.Message ?? string.Empty }; diff --git a/RazorPagesMovie/Migrations/RazorPagesMovieContextModelSnapshot.cs b/RazorPagesMovie/Migrations/RazorPagesMovieContextModelSnapshot.cs index a5c9e8e..8e1d911 100644 --- a/RazorPagesMovie/Migrations/RazorPagesMovieContextModelSnapshot.cs +++ b/RazorPagesMovie/Migrations/RazorPagesMovieContextModelSnapshot.cs @@ -74,6 +74,7 @@ namespace RazorPagesMovie.Migrations .HasColumnType("datetime2"); b.Property("Subject") + .IsRequired() .HasMaxLength(150) .HasColumnType("nvarchar(150)"); diff --git a/RazorPagesMovie/Models/ContactMessage.cs b/RazorPagesMovie/Models/ContactMessage.cs index 4f6b6e3..a83c98a 100644 --- a/RazorPagesMovie/Models/ContactMessage.cs +++ b/RazorPagesMovie/Models/ContactMessage.cs @@ -22,8 +22,9 @@ public class ContactMessage public string? Phone { get; set; } [Display(Name = "Betreff")] + [Required] [StringLength(150)] - public string? Subject { get; set; } + public string Subject { get; set; } = string.Empty; [Display(Name = "Nachricht")] [Required] diff --git a/RazorPagesMovie/Pages/Bewerbung.cshtml b/RazorPagesMovie/Pages/Bewerbung.cshtml index 8ee5744..49039b0 100644 --- a/RazorPagesMovie/Pages/Bewerbung.cshtml +++ b/RazorPagesMovie/Pages/Bewerbung.cshtml @@ -941,7 +941,7 @@ -
+

Haben Sie Fragen oder möchten Sie mit mir in Kontakt treten? Ich freue mich auf Ihre Nachricht. @@ -960,6 +960,7 @@ name="name" placeholder="Name*" required> +
@@ -974,6 +975,7 @@ name="email" placeholder="E-Mail*" required> +
@@ -986,20 +988,23 @@ + placeholder="z. B. 079 123 45 67 oder +41 79 123 45 67"> +
-

Betreff

+

Betreff (Pflichtfeld)

+ placeholder="Betreff*" + required> +
@@ -1015,6 +1020,7 @@ rows="10" placeholder="Nachricht*" required> +
@@ -1084,26 +1090,79 @@ function isValidPhone(value) { if (!value) return true; - var digitCount = (value.match(/\d/g) || []).length; - return /^[0-9+\-\s()]+$/.test(value) && digitCount >= 7 && digitCount <= 15; + return /^(?:\+41|0041|0)[\s-]?\d{2}(?:[\s-]?\d{3})(?:[\s-]?\d{2}){2}$/.test(value); } + function isValidEmail(value) { + return /^[^\s@@]+@@[^\s@@]+\.[^\s@@]+$/.test(value); + } + + var validators = { + name: function (value) { + return value.trim() ? "" : "Bitte geben Sie Ihren Namen ein."; + }, + email: function (value) { + if (!value.trim()) return "Bitte geben Sie Ihre E-Mail-Adresse ein."; + return isValidEmail(value.trim()) ? "" : "Bitte geben Sie eine gültige E-Mail-Adresse ein."; + }, + phone: function (value) { + return isValidPhone(value.trim()) ? "" : "Bitte geben Sie eine gültige Telefonnummer ein."; + }, + subject: function (value) { + return value.trim() ? "" : "Bitte geben Sie einen Betreff ein."; + }, + message: function (value) { + return value.trim() ? "" : "Bitte geben Sie eine Nachricht ein."; + } + }; + + function fieldOf(name) { + return form.querySelector("[name=" + name + "]"); + } + + function validateField(name) { + var field = fieldOf(name); + var feedback = field.closest(".from-box").querySelector(".invalid-feedback"); + var error = validators[name](field.value); + + field.classList.toggle("is-invalid", !!error); + feedback.textContent = error; + + return !error; + } + + function validateAll() { + var allValid = true; + Object.keys(validators).forEach(function (name) { + if (!validateField(name)) allValid = false; + }); + return allValid; + } + + Object.keys(validators).forEach(function (name) { + var field = fieldOf(name); + field.addEventListener("blur", function () { validateField(name); }); + field.addEventListener("input", function () { + if (field.classList.contains("is-invalid")) validateField(name); + }); + }); + form.addEventListener("submit", function (event) { event.preventDefault(); - var payload = { - name: form.querySelector("[name=name]").value, - email: form.querySelector("[name=email]").value, - phone: form.querySelector("[name=phone]").value.trim(), - subject: form.querySelector("[name=subject]").value, - message: form.querySelector("[name=message]").value - }; - - if (!isValidPhone(payload.phone)) { - showMessage("Bitte gib eine gültige Telefonnummer ein.", false); + if (!validateAll()) { + showMessage("Bitte korrigieren Sie die markierten Felder.", false); return; } + var payload = { + name: fieldOf("name").value.trim(), + email: fieldOf("email").value.trim(), + phone: fieldOf("phone").value.trim(), + subject: fieldOf("subject").value.trim(), + message: fieldOf("message").value.trim() + }; + submitButton.disabled = true; fetch("/api/v1/contact", {