Skip to content

Instantly share code, notes, and snippets.

@limboinf
Created April 8, 2017 02:57
Show Gist options
  • Save limboinf/fcc746f03e69213b30081695c87f0768 to your computer and use it in GitHub Desktop.
Save limboinf/fcc746f03e69213b30081695c87f0768 to your computer and use it in GitHub Desktop.
Form Validation and Processing in Go
<h1>Confirmation</h1>
<style type="text/css" media="screen">
.error {
color: red;
}
</style>
<h1>Contacts</h1>
<form action="/" method="POST" accept-charset="utf-8" novalidate>
<div>
{{ with .Errors.Email }}
<p class="error">{{ . }}</p>
{{ end }}
<label for="yourEmail:">yourEmail:</label>
<input type="email" name="email" value="{{ .Email }}">
</div>
<div>
{{ with .Errors.Content}}
<p class="error">{{ . }}</p>
{{ end }}
<label for="yourMessage:">yourMessage:</label>
<textarea name="content" rows="8" cols="40" value="{{ .Content }}"></textarea>
</div>
<div>
<input type="submit" value="Send Message" >
</div>
</form>
package main
import (
"log"
"html/template"
"regexp"
"strings"
"net/http"
"github.com/bmizerany/pat"
)
func main() {
mux := pat.New()
mux.Get("/", http.HandlerFunc(index))
mux.Post("/", http.HandlerFunc(send))
mux.Get("/confirm", http.HandlerFunc(confirm))
log.Println("Listening....")
http.ListenAndServe(":9090", mux)
}
type Message struct {
Email string
Content string
Errors map[string]string
}
func (msg *Message) Validate() bool {
msg.Errors = make(map[string]string)
re := regexp.MustCompile(".+@.+\\..+")
matched := re.Match([]byte(msg.Email))
if matched == false {
msg.Errors["Email"] = "Invalid email"
}
if strings.TrimSpace(msg.Content) == "" {
msg.Errors["Content"] = "Please input message"
}
return len(msg.Errors) == 0
}
func index(w http.ResponseWriter, r *http.Request) {
render(w, "templates/index.html", nil)
}
func confirm(w http.ResponseWriter, r *http.Request) {
render(w, "templates/confirmation.html", nil)
}
func send(w http.ResponseWriter, r *http.Request) {
// Validate form
msg := &Message{
Email: r.FormValue("email"),
Content: r.FormValue("content"), // TODO: design
}
if msg.Validate() == false {
render(w, "templates/index.html", msg)
return
}
http.Redirect(w, r, "/confirm", http.StatusSeeOther)
}
func render(w http.ResponseWriter, filename string, data interface{}) {
tmpl, err := template.ParseFiles(filename)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
if err := tmpl.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
.
├── main.go
└── templates
    ├── confirmation.html
    └── index.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment