https://github.com/gernest/gforms
forms library for golang
https://github.com/gernest/gforms
Last synced: 7 months ago
JSON representation
forms library for golang
- Host: GitHub
- URL: https://github.com/gernest/gforms
- Owner: gernest
- License: mit
- Created: 2015-07-19T04:28:08.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2015-07-19T04:31:25.000Z (over 10 years ago)
- Last Synced: 2025-06-20T01:03:35.408Z (7 months ago)
- Language: Go
- Homepage:
- Size: 195 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GForms
A flexible forms validation and rendering library for golang web development.
Inspired by [django-forms](https://docs.djangoproject.com/en/dev/topics/forms/) and [wtforms](https://github.com/wtforms/wtforms).
[](https://app.wercker.com/project/bykey/51a7f6720baf8e67a28241790380d19b)
## Overview
* Validate HTTP request
* Rendering form-html
* Support parsing content-type "form-urlencoded", "json"
* Support many widgets for form field.
# Getting Started
## Install
```
go get github.com/bluele/gforms
```
## Examples
See [examples](https://github.com/bluele/gforms/tree/master/examples).
## Usage
### Define Form
```go
userForm := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required(),
gforms.MaxLengthValidator(32),
},
),
gforms.NewFloatField(
"weight",
gforms.Validators{},
),
))
```
### Validate HTTP request
Server ([code](https://github.com/bluele/gforms/blob/master/examples/simple_form.go)):
```go
type User struct {
Name string `gforms:"name"`
Weight float32 `gforms:"weight"`
}
func main() {
tplText := `
{{range $i, $field := .Fields}}
{{$field.GetName}}: {{$field.Html}}
{{range $ei, $err := $field.Errors}}{{$err}}{{end}}
{{end}}
`
tpl := template.Must(template.New("tpl").Parse(tplText))
userForm := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required(),
gforms.MaxLengthValidator(32),
},
),
gforms.NewFloatField(
"weight",
gforms.Validators{},
),
))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
form := userForm(r)
if r.Method != "POST" {
tpl.Execute(w, form)
return
}
if !form.IsValid() {
tpl.Execute(w, form)
return
}
user := User{}
form.MapTo(&user)
fmt.Fprintf(w, "ok: %v", user)
})
http.ListenAndServe(":9000", nil)
}
```
Client:
```
# show html form
$ curl -X GET localhost:9000/users
name:
weight:
# valid request
$ curl -X POST localhost:9000/users -d 'name=bluele&weight=71.9'
ok: {bluele 71.9}
# "name" field is required.
$ curl -X POST localhost:9000/users -d 'weight=71.9'
name:
This field is required.
weight:
```
### Define Form by Struct Model
```go
type User struct {
Name string `gforms:"name"`
Weight float32 `gforms:"weight"`
}
func initForm() {
userForm := gforms.DefineModelForm(User{}, gforms.NewFields(
// override User.name field
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required(),
gforms.MaxLengthValidator(32),
},
),
))
/* equal an above defined form.
userForm := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required(),
gforms.MaxLengthValidator(32),
},
),
gforms.NewFloatField(
"weight",
gforms.Validators{},
),
))
*/
}
```
## Render HTML
### FormInstance#Html
```go
form := userForm(r)
fmt.Println(form.Html())
/*
# Output
*/
```
### FieldInstance#Html
```
form := userForm(r)
fmt.Println(form.GetField("name").Html())
/*
# Output
*/
```
## Parse request data
### (Default) Parse `*http.Request` to create a new `FormInstance`.
```go
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
form := userForm(r)
...
}
```
### Parse `net/url.Values` to create a new `FormInstance`.
```go
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// parse querystring values.
form := userForm.FromUrlValues(r.URL.Query())
...
}
```
## Customize Formfield attributes
```go
customForm := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required(),
},
gforms.TextInputWidget(
map[string]string{
"class": "custom",
},
)),
))
form := customForm(r)
fmt.Println(form.Html())
/*
# Output
*/
```
## Custom Validation error message
```go
userForm := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"name",
gforms.Validators{
gforms.Required("Custom error required message."),
gforms.MaxLengthValidator(32, "Custom error maxlength message."),
},
),
))
```
## Support Fields
### TextField
It maps value to FormInstance.CleanedData as type `string`.
```go
gforms.NewTextField(
"text",
gforms.Validators{},
)
```
### BooleanField
It maps value to FormInstance.CleanedData as type `bool`.
```go
gforms.NewBooleanField(
"checked",
gforms.Validators{},
)
```
### IntegerField
It maps value to FormInstance.CleanedData as type `int`.
```go
gforms.NewIntegerField(
"number",
gforms.Validators{},
)
```
### FloatField
It maps value to FormInstance.CleanedData as type `float32` or `float64`.
```go
gforms.NewFloatField(
"floatNumber",
gforms.Validators{},
)
```
### MultipleTextField
It maps value to FormInstance.CleanedData as type `[]string`.
```go
gforms.NewMultipleTextField(
"texts",
gforms.Validators{},
)
```
### DateTimeField
It maps value to FormInstance.CleanedData as type `time.Time`.
```go
gforms.NewDateTimeField(
"date",
DefaultDateTimeFormat,
gforms.Validators{},
)
```
## Support Validators
### Required validator
Added an error msg to FormInstance.Errors() if the field is not provided.
```go
gforms.Validators{
gforms.Required(),
},
```
### Regexp validator
Added an error msg to FormInstance.Errors() if the regexp doesn't matched a value.
```go
gforms.Validators{
gforms.RegexpValidator(`number-\d+`),
},
```
### Email validator
Added an error msg to FormInstance.Errors() if a value doesn't looks like an email address.
```go
gforms.Validators{
gforms.EmailValidator(),
},
```
### URL Validator
Added an error msg to FormInstance.Errors() if a value doesn't looks like an url.
```go
gforms.Validators{
gforms.URLValidator(),
},
```
### MinLength Validator
Added an error msg to FormInstance.Errors() if the length of value is less than specified first argument.
```go
gforms.Validators{
gforms.MinLengthValidator(16),
},
```
### MaxLength Validator
Added an error msg to FormInstance.Errors() if the length of value is greater than specified first argument.
```go
gforms.Validators{
gforms.MaxLengthValidator(256),
},
```
### MinValueValidator
Added an error msg to FormInstance.Errors() if value is less than specified first argument.
```go
gforms.Validators{
gforms.MinValueValidator(16),
},
```
### MaxValueValidator
Added an error msg to FormInstance.Errors() if value is greater than specified first argument.
```go
gforms.Validators{
gforms.MaxValueValidator(256),
},
```
## Support Widgets
### SelectWidget
```go
Form := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"gender",
gforms.Validators{
gforms.Required(),
},
gforms.SelectWidget(
map[string]string{
"class": "custom",
},
func() gforms.SelectOptions {
return gforms.StringSelectOptions([][]string{
{"Men", "0"},
{"Women", "1"},
})
},
),
),
))
form = Form()
fmt.Println(form.Html())
/*
# output
Men
Women
*/
```
### RadioSelectWidget
```go
Form := gforms.DefineForm(gforms.NewFields(
gforms.NewTextField(
"lang",
gforms.Validators{
gforms.Required(),
},
gforms.RadioSelectWidget(
map[string]string{
"class": "custom",
},
func() gforms.RadioOptions {
return gforms.StringRadioOptions([][]string{
{"Golang", "0", "false", "false"},
{"Python", "1", "false", "true"},
})
},
),
),
))
form = Form()
fmt.Println(form.Html())
/*
# output
Golang
Python
*/
```
### CheckboxMultipleWidget
```go
Form := gforms.DefineForm(gforms.NewFields(
gforms.NewMultipleTextField(
"lang",
gforms.Validators{
gforms.Required(),
},
gforms.CheckboxMultipleWidget(
map[string]string{
"class": "custom",
},
func() gforms.CheckboxOptions {
return gforms.StringCheckboxOptions([][]string{
{"Golang", "0", "false", "false"},
{"Python", "1", "false", "true"},
})
},
),
),
))
form := Form()
fmt.Println(form.Html())
/*
# output
Golang
Python
*/
```
# TODO
* Support FileField, DateField, DateTimeField
* Writing more godoc and unit tests.
* Improve performance.
# Author
**Jun Kimura**
*
*