func (bf *BaseField) Error(errorType string, errorMsg string) *BaseField {
    if bf.option.ErrorMsgs == nil {
        bf.option.ErrorMsgs = make(map[string]string)
    }
    bf.option.ErrorMsgs[errorType] = errorMsg
    return bf
}
The return value is the BaseField, so calls can be chained
package form
import (
    "net/http"
    "regexp"
)
type Form struct {
    Name    string
    Action  string
    Fields  map[string]Field
    IsValid bool
}
func (fm *Form) Valid() bool {
    isValid := true
    for _, field := range fm.Fields {
        var vr *ValidResult = field.Valid()
        if !vr.IsValid {
            isValid = false
        } else {
            field.CleanValue()
        }
    }
    fm.IsValid = isValid
    return isValid
}
func (fm *Form) Values() map[string]string {
    r := make(map[string]string)
    for name, field := range fm.Fields {
        r[name] = field.Value()
    }
    return r
}
func (fm *Form) CleanValues() map[string]interface{} {
    r := make(map[string]interface{})
    for name, field := range fm.Fields {
        r[name] = field.CleanValue()
    }
    return r
}
func (fm *Form) Errors() map[string][]string {
    r := make(map[string][]string)
    for name, field := range fm.Fields {
        if !field.IsValid() {
            r[name] = []string{field.NickName(), field.ErrorMsg()}
        }
    }
    return r
}
func (fm *Form) FillByMap(m map[string]string) {
    if m == nil {
        return
    }
    for k, v := range m {
        if field, ok := fm.Fields[k]; ok {
            field.SetValue(v)
        }
    }
}
func (fm *Form) FillByRequest(req *http.Request) {
    for k, f := range fm.Fields {
        f.SetValue(req.FormValue(k))
    }
}
func NewForm(fields ...Field) *Form {
    f := &Form{
        Fields: make(map[string]Field),
    }
    for _, field := range fields {
        f.Fields[field.Name()] = field
    }
    return f
}
type Field interface {
    Name() string
    NickName() string
    ErrorMsg() string
    Value() string
    SetValue(s string)
    CleanValue() interface{}
    IsValid() bool
    Valid() *ValidResult
}
type FieldOption struct {
    Required  bool
    NotTrim   bool  
    Range     [2]int
    ErrorMsgs map[string]string
}
type BaseField struct {
    name       string
    nickname   string
    errorMsg   string
    value      string
    cleanValue interface{}
    isValid    bool
    validater  Validater
    option     *FieldOption
}
func (bf *BaseField) init(name string, nickname string, required bool) {
    bf.name = name
    bf.nickname = nickname
    bf.option = &FieldOption{Required: required}
}
func (bf *BaseField) Field() Field {
    return bf
}
func (bf *BaseField) Name() string {
    return bf.name
}
func (bf *BaseField) NickName() string {
    return bf.nickname
}
func (bf *BaseField) ErrorMsg() string {
    return bf.errorMsg
}
func (bf *BaseField) Value() string {
    return bf.value
}
func (bf *BaseField) SetValue(val string) {
    bf.value = val
}
func (bf *BaseField) CleanValue() interface{} {
    return bf.cleanValue
}
func (bf *BaseField) IsValid() bool {
    return bf.isValid
}
func (bf *BaseField) Valid() *ValidResult {
    vr := bf.validater.Valid(bf.value, bf.option)
    bf.isValid = vr.IsValid
    bf.cleanValue = vr.CleanValue
    bf.errorMsg = vr.ErrorMsg
    return vr
}
func (bf *BaseField) Required(r bool) *BaseField {
    bf.option.Required = r
    return bf
}
func (bf *BaseField) Max(max int) *BaseField {
    bf.option.Range[1] = max
    return bf
}
func (bf *BaseField) Min(min int) *BaseField {
    bf.option.Range[0] = min
    return bf
}
func (bf *BaseField) MaxLength(max int) *BaseField {
    bf.option.Range[1] = max
    return bf
}
func (bf *BaseField) MinLength(min int) *BaseField {
    bf.option.Range[0] = min
    return bf
}
func (bf *BaseField) Range(min int, max int) *BaseField {
    bf.option.Range = [2]int{min, max}
    return bf
}