Skip to content

Commit 621ef63

Browse files
committed
Create form page to add new snippets
1 parent 4375ab6 commit 621ef63

File tree

5 files changed

+98
-11
lines changed

5 files changed

+98
-11
lines changed

client.http

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,18 @@ Content-Type: application/json
99
###
1010

1111
# @name view_snippet
12-
GET {{baseUrl}}/snippet/view?id=1
12+
GET {{baseUrl}}/snippet/view/1
1313
Content-Type: application/json
1414

1515
###
1616

1717
# @name create_snippet
1818
POST {{baseUrl}}/snippet/create
19-
Content-Type: application/json
19+
Content-Type: application/x-www-form-urlencoded
2020

21-
{
22-
"title": "Snippet Title",
23-
"content": "Snippet Content"
24-
}
21+
title="title"
22+
&content="content"
23+
&expires=7
2524

2625
###
2726

cmd/web/handlers.go

+59-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55
"fmt"
66
"lets-go-snippetbox/internal/models"
77
"net/http"
8+
"slices"
89
"strconv"
10+
"strings"
11+
"unicode/utf8"
912

1013
"github.com/julienschmidt/httprouter"
1114
)
@@ -50,15 +53,66 @@ func (app *application) snippetView(w http.ResponseWriter, r *http.Request) {
5053
}
5154

5255
func (app *application) snippetCreate(w http.ResponseWriter, r *http.Request) {
53-
w.Write([]byte("Display the form for creating a new snippet..."))
56+
data := app.newTemplateData(r)
57+
58+
data.Form = snippetCreateForm{
59+
Expires: 365,
60+
}
61+
62+
app.render(w, http.StatusOK, "create.html", data)
63+
}
64+
65+
type snippetCreateForm struct {
66+
Title string
67+
Content string
68+
Expires int
69+
FieldErrors map[string]string
5470
}
5571

5672
func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request) {
57-
title := "O snail"
58-
content := "O snail\nClimb Mount Fuji,\nBut slowly, slowly!\n\n- Kobayashi Issa"
59-
expires := 7
73+
err := r.ParseForm()
74+
if err != nil {
75+
app.clientError(w, http.StatusBadRequest)
76+
return
77+
}
78+
79+
expires, err := strconv.Atoi(r.PostForm.Get("expires"))
80+
if err != nil {
81+
app.clientError(w, http.StatusBadRequest)
82+
return
83+
}
84+
85+
form := snippetCreateForm{
86+
Title: r.PostForm.Get("title"),
87+
Content: r.PostForm.Get("content"),
88+
Expires: expires,
89+
FieldErrors: map[string]string{},
90+
}
91+
92+
if strings.TrimSpace(form.Title) == "" {
93+
form.FieldErrors["title"] = "this field cannot be blank"
94+
} else if utf8.RuneCountInString(form.Title) > 100 {
95+
form.FieldErrors["title"] = "this field cannot be more than 100 characters long"
96+
}
97+
98+
if strings.TrimSpace(form.Content) == "" {
99+
form.FieldErrors["content"] = "this field cannot be blank"
100+
}
101+
102+
if !slices.Contains([]int{1, 7, 365}, form.Expires) {
103+
form.FieldErrors["expires"] = "this field must equal 1, 7 or 365"
104+
}
105+
106+
if len(form.FieldErrors) > 0 {
107+
data := app.newTemplateData(r)
108+
data.Form = form
109+
110+
app.render(w, http.StatusUnprocessableEntity, "create.html", data)
111+
112+
return
113+
}
60114

61-
id, err := app.snippets.Insert(title, content, expires)
115+
id, err := app.snippets.Insert(form.Title, form.Content, form.Expires)
62116
if err != nil {
63117
app.serverError(w, err)
64118
return

cmd/web/templates.go

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type templateData struct {
1111
CurrentYear int
1212
Snippet *models.Snippet
1313
Snippets []*models.Snippet
14+
Form any
1415
}
1516

1617
func humanDate(t time.Time) string {

ui/html/pages/create.html

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{{define "title"}}Create a New Snippet{{end}}
2+
3+
{{define "main"}}
4+
<form action='/snippet/create' method='POST'>
5+
<div>
6+
<label>Title:</label>
7+
{{with .Form.FieldErrors.title}}
8+
<label class='error'>{{.}}</label>
9+
{{end}}
10+
<input type='text' name='title' value='{{.Form.Title}}'>
11+
</div>
12+
<div>
13+
<label>Content:</label>
14+
{{with .Form.FieldErrors.content}}
15+
<label class='error'>{{.}}</label>
16+
{{end}}
17+
<textarea name='content'>{{.Form.Content}}</textarea>
18+
</div>
19+
<div>
20+
<label>Delete in:</label>
21+
{{with .Form.FieldErrors.expires}}
22+
<label class='error'>{{.}}</label>
23+
{{end}}
24+
<input type='radio' name='expires' value='365' {{if (eq .Form.Expires 365)}}checked{{end}}> One Year
25+
<input type='radio' name='expires' value='7' {{if (eq .Form.Expires 7)}}checked{{end}}> One Week
26+
<input type='radio' name='expires' value='1' {{if (eq .Form.Expires 1)}}checked{{end}}> One Day
27+
</div>
28+
<div>
29+
<input type='submit' value='Publish snippet'>
30+
</div>
31+
</form>
32+
{{end}}

ui/html/partials/nav.html

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{{define "nav"}}
22
<nav>
33
<a href='/'>Home</a>
4+
<a href='/snippet/create'>Create snippet</a>
45
</nav>
56
{{end}}

0 commit comments

Comments
 (0)