Categorygithub.com/filwisher/forms
modulepackage
0.0.0-20200806155755-d7797dbb21fe
Repository: https://github.com/filwisher/forms.git
Documentation: pkg.go.dev

# README

forms

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,
	})
}

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

No description provided by the author