From 87dfd26268ce2f83ad1126bf65d9268708002e3a Mon Sep 17 00:00:00 2001 From: Muyao CHEN Date: Mon, 1 Jul 2024 13:37:03 +0200 Subject: [PATCH] Server Side form validation 3 --- internal/forms/forms.go | 28 +++++++++++++++++++++++----- internal/handlers/handlers.go | 11 ++++++++++- templates/make-reservation.page.tmpl | 17 +++++++++++++---- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/internal/forms/forms.go b/internal/forms/forms.go index 0a2116d..bb8be67 100644 --- a/internal/forms/forms.go +++ b/internal/forms/forms.go @@ -1,8 +1,10 @@ package forms import ( + "fmt" "net/http" "net/url" + "strings" ) // Form creates a custom form struct, embeds a url.Values object @@ -19,17 +21,33 @@ func New(data url.Values) *Form { } } +// Required checks required fields +func (f *Form) Required(fields ...string) { + for _, field := range fields { + value := f.Get(field) + if strings.TrimSpace(value) == "" { + f.Errors.Add(field, "This field cannot be blank") + } + } +} + // Has checks if form field is in post and not emtpy func (f *Form) Has(field string, r *http.Request) bool { x := r.Form.Get(field) - if x == "" { - f.Errors.Add(field, "This field cannot be blank") - return false - } - return true + return x != "" } // Valid returns true if there are no errors, otherwise false func (f *Form) Valid() bool { return len(f.Errors) == 0 } + +// MinLength checks for string minimum length +func (f *Form) MinLength(field string, length int, r *http.Request) bool { + value := r.Form.Get(field) + if len(value) < length { + f.Errors.Add(field, fmt.Sprintf("This field must have at least %d letters", length)) + return false + } + return true +} diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 1bf53fe..2b28efa 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -69,8 +69,16 @@ func (m *Repository) Majors(w http.ResponseWriter, r *http.Request) { // MakeReservation is the make reservation page handler func (m *Repository) MakeReservation(w http.ResponseWriter, r *http.Request) { + // For the first time render emptyReservation so that this object is + // filled with the info when sent back. + var emptyReservation models.Reservation + data := make(map[string]interface{}) + + data["reservation"] = emptyReservation + render.RenderTemplate(w, r, "make-reservation.page.tmpl", &models.TemplateData{ Form: forms.New(nil), + Data: data, }) } @@ -91,7 +99,8 @@ func (m *Repository) PostMakeReservation(w http.ResponseWriter, r *http.Request) form := forms.New(r.PostForm) - form.Has("first_name", r) + form.Required("first_name", "last_name", "email") + form.MinLength("first_name", 2, r) if !form.Valid() { data := make(map[string]interface{}) diff --git a/templates/make-reservation.page.tmpl b/templates/make-reservation.page.tmpl index 220945d..edbc3d4 100644 --- a/templates/make-reservation.page.tmpl +++ b/templates/make-reservation.page.tmpl @@ -5,6 +5,7 @@

Make reservation

+ {{$res := index .Data "reservation"}}
@@ -15,19 +16,27 @@ {{end}} + value="{{$res.FirstName}}" required autocomplete="off">
- + {{with .Form.Errors.Get "last_name"}} + + {{end}} +
- + {{with .Form.Errors.Get "email"}} + + {{end}} +
- +