Easily generate HTML form inputs from your structs. Parse HTTP request parameters
back into structs (like https://github.com/gorilla/schema).
Supports:
- slices
- nested types
- generating HTML from structs
- parsing structs from HTTP requests
- prefilling input values
- custom
id
and class
attributes
- configuration through struct tags or option parameters
Usage
Types to HTML
type NewUser struct {
Username string `forms:"username"`
Password string `forms:"password,type=password"`
Confirm string `forms:"confirm-password,type=password"`
}
var tmpl = template.Must(template.New("").Parse("{{ .form }}"))
func handler(w http.ResponseWriter, r *http.Request) {
user := &NewUser{}
form, err := forms.Render(user)
if err != nil {
...
}
tmpl.Execute(w, map[string]interface{}{"form": form})
}
The main function is forms.Render(interface{}) (template.HTML, error)
. This
returns a set of HTML inputs that can be nested directly in your
html/template.Template
.
The input types have sensible defaults but can be overwridden with struct tags
or with explicit Options
:
form.RenderOpts(NewUserForm{}, map[string]Options{
"Username": form.Options{Name: "username", ID: "username-field"},
})
Nested structs are supported and field names are namespaced. These types:
type Address struct {
Line1 string
Line2 string
City string
}
type Person struct {
Name string
Address Address
}
will generate this form:
<input type='text' name='Name'>
<input type='text' name='Address.Line1'>
<input type='text' name='Address.Line2'>
<input type='text' name='Address.City'>
Slices are supported. These types:
type Pet struct { Name string }
type Person struct {
Pets []Pet
}
person := &Person{
Pets: []Pet{{Name: "hector"},{Name: "biggles"}},
}
will generate this form:
<input type='text' name='Person.Pets.1.Name' value='hector'>
<input type='text' name='Person.Pets.2.Name' value='biggles'>
HTTP to Types
type NewUser struct {
Username string `forms:"username"`
Password string `forms:"password,type=password"`
Confirm string `forms:"confirm-password,type=password"`
}
// This is just a *github.com/gorilla/schema.Decoder
var decoder = forms.NewDecoder()
func handler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
...
}
newUser := &NewUser{}
err = decoder.Decode(&newUser, r.PostForm)
if err != nil {
...
}
}
Example
Full example
package main
import (
"html/template"
"os"
"github.com/filwisher/forms"
)
type NewUser struct {
Username string `form:"username,type=text"`
Password string `form:"password,type=password"`
Confirm string `form:"password,type=confirm"`
}
var base = template.Must(template.New("base").Parse(`
<!DOCTYPE html>
<html>
<head></head>
<body>
<form>
{{ .form }}
</form>
</body>
</html>`))
func main() {
form, err := forms.Render(NewUser{})
if err != nil {
panic(err)
}
base.Execute(os.Stdout, map[string]interface{}{
"form": form,
})
}