add form validation

This commit is contained in:
Philipp 2021-08-29 18:22:08 +02:00
parent 82f11b254b
commit 3f2cbcea33
No known key found for this signature in database
GPG Key ID: 276B613AF9DBE9C3
8 changed files with 131 additions and 18 deletions

View File

@ -20,8 +20,10 @@
<div class="text-right">
<form action="/threads/{{.Thread.ID}}/{{.Post.ID}}" method="POST">
{{.CSRF}}
<textarea name="content" class="form-control border-0 border-bottom-1 p-3"
placeholder="What are your thoughts?" rows="4"></textarea>
<textarea name="content" class="form-control border-0 border-bottom-1 p-3 {{with .Form.Errors.Content}}is-invalid{{end}}"
placeholder="What are your thoughts?" rows="4">
{{- with .Form.Content}}{{.}}{{end -}}
</textarea>
<div class="border-top p-1">
<button class="btn btn-primary btn-sm">Comment</button>
</div>

View File

@ -9,12 +9,19 @@
{{.CSRF}}
<div class="form-group">
<label>Title</label>
<input name="title" type="text" class="form-control" placeholder="Give your post a great title">
<input name="title" type="text" class="form-control {{with .Form.Errors.Title}}is-invalid{{end}}" placeholder="Give your post a great title" value="{{with .Form.Title}}{{.}}{{end}}">
{{with .Form.Errors.Title}}
<div class="invalid-feedack">{{.}}</div>
{{end}}
</div>
<div class="form-group">
<label>Text</label>
<textarea name="content" class="form-control" rows="3"
placeholder="Tell people about your thoughts"></textarea>
<textarea name="content" class="form-control {{with .Form.Errors.Content}}is-invalid{{end}}" rows="3" placeholder="Tell people about your thoughts">
{{- with .Form.Content}}{{.}}{{end -}}
</textarea>
{{with .Form.Errors.Content}}
<div class="invalid-feedack">{{.}}</div>
{{end}}
</div>
<button type="submit" class="btn btn-primary">Submit Post</button>
</form>

View File

@ -7,12 +7,20 @@
{{.CSRF}}
<div class="form-group">
<label>Title</label>
<input name="title" type="text" class="form-control" placeholder="Give your thread a great title">
<input name="title" type="text" class="form-control {{with .Form.Errors.Title}}is-invalid{{end}}" placeholder="Give your thread a great title" value="{{with .Form.Title}}{{.}}{{end}}">
{{with .Form.Errors.Title}}
<div class="invalid-feedack">{{.}}</div>
{{end}}
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" class="form-control" rows="3"
placeholder="Tell people what your thread is about"></textarea>
<textarea name="description" class="form-control {{with .Form.Errors.Description}}is-invalid{{end}}" rows="3"
placeholder="Tell people what your thread is about">
{{- with .Form.Description}}{{.}}{{end -}}
</textarea>
{{with .Form.Errors.Description}}
<div class="invalid-feedack">{{.}}</div>
{{end}}
</div>
<button type="submit" class="btn btn-primary">Create Thread</button>
</form>

View File

@ -16,7 +16,15 @@ type CommentHandler struct {
func (h *CommentHandler) Store() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
content := r.FormValue("content")
form := CreateCommentForm{
Content: r.FormValue("content"),
}
if !form.Validate() {
h.sessions.Put(r.Context(), "form", form)
http.Redirect(w, r, r.Referer(), http.StatusFound)
return
}
idStr := chi.URLParam(r, "postID")
id, err := uuid.Parse(idStr)
@ -28,7 +36,7 @@ func (h *CommentHandler) Store() http.HandlerFunc {
if err := h.store.CreateComment(&goddit.Comment{
ID: uuid.New(),
PostID: id,
Content: content,
Content: form.Content,
}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

68
web/forms.go Normal file
View File

@ -0,0 +1,68 @@
package web
import "encoding/gob"
func init() {
gob.Register(CreatePostForm{})
gob.Register(CreateThreadForm{})
gob.Register(CreateCommentForm{})
gob.Register(FormErrors{})
}
type FormErrors map[string]string
type CreatePostForm struct {
Title string
Content string
Errors FormErrors
}
func (f *CreatePostForm) Validate() bool {
f.Errors = FormErrors{}
if f.Title == "" {
f.Errors["Title"] = "Please enter a title!"
}
if f.Content == "" {
f.Errors["Content"] = "Please enter a text!"
}
return len(f.Errors) == 0
}
type CreateThreadForm struct {
Title string
Description string
Errors FormErrors
}
func (f *CreateThreadForm) Validate() bool {
f.Errors = FormErrors{}
if f.Title == "" {
f.Errors["Title"] = "Please enter a title!"
}
if f.Description == "" {
f.Errors["Description"] = "Please enter a description!"
}
return len(f.Errors) == 0
}
type CreateCommentForm struct {
Content string
Errors FormErrors
}
func (f *CreateCommentForm) Validate() bool {
f.Errors = FormErrors{}
if f.Content == "" {
f.Errors["Content"] = "Please enter a comment!"
}
return len(f.Errors) == 0
}

View File

@ -102,8 +102,15 @@ func (h *PostHandler) Show() http.HandlerFunc {
func (h *PostHandler) Store() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
title := r.FormValue("title")
content := r.FormValue("content")
form := CreatePostForm{
Title: r.FormValue("title"),
Content: r.FormValue("content"),
}
if !form.Validate() {
h.sessions.Put(r.Context(), "form", form)
http.Redirect(w, r, r.Referer(), http.StatusFound)
return
}
idStr := chi.URLParam(r, "id")
@ -122,8 +129,8 @@ func (h *PostHandler) Store() http.HandlerFunc {
p := &goddit.Post{
ID: uuid.New(),
ThreadID: t.ID,
Title: title,
Content: content,
Title: form.Title,
Content: form.Content,
}
if err := h.store.CreatePost(p); err != nil {

View File

@ -22,6 +22,7 @@ func NewSessionsManager(dataSourceName string) (*scs.SessionManager, error) {
type SessionData struct {
FlashMessage string
Form interface{}
// UserID uuid.UUID
}
@ -31,5 +32,10 @@ func GetSessionData(session *scs.SessionManager, ctx context.Context) SessionDat
data.FlashMessage = session.PopString(ctx, "flash")
// data.UserID, _ = session.Get(ctx "user_id").(uuid.UUID)
data.Form = session.Pop(ctx, "form")
if data.Form == nil {
data.Form = map[string]string{}
}
return data
}

View File

@ -91,13 +91,20 @@ func (h *ThreadHandler) Show() http.HandlerFunc {
func (h *ThreadHandler) Store() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
title := r.FormValue("title")
description := r.FormValue("description")
form := CreateThreadForm{
Title: r.FormValue("title"),
Description: r.FormValue("description"),
}
if !form.Validate() {
h.sessions.Put(r.Context(), "form", form)
http.Redirect(w, r, r.Referer(), http.StatusFound)
return
}
if err := h.store.CreateThread(&goddit.Thread{
ID: uuid.New(),
Title: title,
Description: description,
Title: form.Title,
Description: form.Description,
}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return