Server-side form validation 1

This commit is contained in:
Muyao CHEN 2024-06-30 17:08:47 +02:00
parent 7294254e13
commit 8394832428
6 changed files with 59 additions and 2 deletions

View File

@ -26,6 +26,7 @@ func routes(app *config.AppConfig) http.Handler {
mux.Post("/availability", handlers.Repo.PostAvailability) mux.Post("/availability", handlers.Repo.PostAvailability)
mux.Post("/availability-json", handlers.Repo.AvailabilityJSON) mux.Post("/availability-json", handlers.Repo.AvailabilityJSON)
mux.Get("/make-reservation", handlers.Repo.MakeReservation) mux.Get("/make-reservation", handlers.Repo.MakeReservation)
mux.Post("/make-reservation", handlers.Repo.PostMakeReservation)
fileServer := http.FileServer(http.Dir("./static/")) fileServer := http.FileServer(http.Dir("./static/"))
mux.Handle("/static/*", http.StripPrefix("/static", fileServer)) mux.Handle("/static/*", http.StripPrefix("/static", fileServer))

18
internal/forms/errors.go Normal file
View File

@ -0,0 +1,18 @@
package forms
type errors map[string][]string
// Add adds an error message for a given form field
func (e errors) Add(field, message string) {
e[field] = append(e[field], message)
}
// Get returns the first error message
func (e errors) Get(field string) string {
es := e[field]
if len(es) == 0 {
return ""
}
return es[0]
}

26
internal/forms/forms.go Normal file
View File

@ -0,0 +1,26 @@
package forms
import (
"net/http"
"net/url"
)
// Form creates a custom form struct, embeds a url.Values object
type Form struct {
url.Values
Errors errors
}
// New initializes a form struct
func New(data url.Values) *Form {
return &Form{
data,
errors(map[string][]string{}),
}
}
// 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)
return x != ""
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"go-udemy-web-1/internal/config" "go-udemy-web-1/internal/config"
"go-udemy-web-1/internal/forms"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"go-udemy-web-1/internal/render" "go-udemy-web-1/internal/render"
"log" "log"
@ -68,7 +69,13 @@ func (m *Repository) Majors(w http.ResponseWriter, r *http.Request) {
// MakeReservation is the make reservation page handler // MakeReservation is the make reservation page handler
func (m *Repository) MakeReservation(w http.ResponseWriter, r *http.Request) { func (m *Repository) MakeReservation(w http.ResponseWriter, r *http.Request) {
render.RenderTemplate(w, r, "make-reservation.page.tmpl", &models.TemplateData{}) render.RenderTemplate(w, r, "make-reservation.page.tmpl", &models.TemplateData{
Form: forms.New(nil),
})
}
// PostMakeReservation is the make reservation page post handler
func (m *Repository) PostMakeReservation(w http.ResponseWriter, r *http.Request) {
} }
// Availability is the search for availability page handler // Availability is the search for availability page handler

View File

@ -1,5 +1,7 @@
package models package models
import "go-udemy-web-1/internal/forms"
// TemplateData holds data sent from handlers to templates // TemplateData holds data sent from handlers to templates
type TemplateData struct { type TemplateData struct {
StringMap map[string]string StringMap map[string]string
@ -10,4 +12,5 @@ type TemplateData struct {
Flash string Flash string
Warning string Warning string
Error string Error string
Form *forms.Form
} }

View File

@ -5,7 +5,9 @@
<div class="col"> <div class="col">
<h1 class="text-center mt-3">Make reservation</h1> <h1 class="text-center mt-3">Make reservation</h1>
<form method="post" action="" class="needs-validation" novalidate> <!-- <form method="post" action="" class="needs-validation" novalidate> -->
<form method="post" action="" class="" novalidate>
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<div class="form-group mt-5"> <div class="form-group mt-5">
<label for="first_name">First name:</label> <label for="first_name">First name:</label>
<input type="text" name="first_name" id="first_name" class="form-control" required <input type="text" name="first_name" id="first_name" class="form-control" required