Documentation ¶
Overview ¶
Package aform provides functionalities for working effectively with forms.
Introduction ¶
This package provides simple tools to create forms, to render them as HTML and to do forms' input validations.
Let's suppose you want to create a form to get the user's name. You'll need something like this in your template.
<form action="/your-name" method="post"> <label for="your_name">Your name: </label> <input id="your_name" type="text" name="your_name" value="{{ .CurrentName }}"> <input type="submit" value="OK"> </form>
This HTML code tells the browser to return the form data to the URL /your-name, using the POST method. It will display a text field labeled "Your name:" and a button "OK". If the template context contains the CurrentName variable, it will be used to pre-fill the your_name field.
You'll need a handler to render the template containing the HTML form and providing the CurrentName value.
When the form is submitted, the POST request which is sent to the server will contain the form data. So, you'll also need a handler for the POST request to the path /your-name. This handler will have to find the appropriate key/values pairs in the request and to process them.
Form Creation ¶
We already know what we want our HTML form to look like. Our starting point to create it with aform is this:
nameForm := aform.Must(aform.New( aform.WithCharField(aform.Must(aform.DefaultCharField("Your name"))), ))
This creates a Form with a single CharField. We used DefaultCharField that creates a CharField with reasonable defaults like a maximum length of 256. It means that the browser should prevent the user from entering more characters than that. It also means that when your application HTTP handler receives the form back from the browser, aform will validate the length of the data.
A Form has a Form.IsValid function, which runs validation for all its fields. When this function is called, if all fields contain valid data, it will return true and make the form's data accessible via Form.CleanedData function.
The whole nameForm, when rendered for the first time, will look like:
<div><label for="id_your_name">Your name</label><input type="text" name="your_name" id="id_your_name" maxlength="256" required></div>
Note that it does not include the <form> tags, or a submit button. We’ll have to provide those ourselves in the template.
The HTTP handler ¶
Form data sent back to the server is processed by a handler. To handle the form we need to create the form in the handler for the path where we want it to be published:
func nameHandler(w http.ResponseWriter, req *http.Request) { nameForm := aform.Must(aform.New( aform.WithCharField(aform.Must(aform.DefaultCharField("Your name"))), )) // if this is a POST request we need to process the form data if req.Method == "POST" { // Populate the form with data from the request: nameForm.BindRequest(req) // check whether it's valid: if nameForm.IsValid() { // process the data with Form.CleanedData // ... // redirect to a new URL: http.Redirect(w, req, "/congratulations", http.StatusFound) } } _ = tmpl.ExecuteTemplate(w, "name", map[string]any{"form": nameForm}) }
If the handler is triggered by a GET request, it will create an empty form and place it in the template context to be rendered. This is what we can expect to happen the first time we visit the URL.
If the form is submitted using a POST request, the handler will populate the form with data from the request:
nameForm.BindRequest(req)
This is called “binding data to the form” (it is now a bound form).
We call the Form.IsValid method; if it’s not True, we go back to the template with the form. This time the form is no longer empty (unbound) so the HTML form will be populated with the data previously submitted, where it can be edited and corrected as required. The HTML form will also display errors found by the validation.
If Form.IsValid is True, we’ll now be able to find all the validated form data in its CleanedData returned by Form.CleanedData. We can use this data to update the database or do other processing before sending an HTTP redirect to the browser telling it where to go next.
The template ¶
We don’t need to do much in our template:
<form action="/your-name" method="post"> {{ .form.AsDiv }} {{/* Add CSRF */}} <button type="submit">OK</button> </form>
All the form’s fields and their attributes will be unpacked into HTML markup from that:
{{ .form.AsDiv }}
Bound and unbound forms ¶
A Form is either bound to a set of data, or unbound. If it’s bound to a set of data, it’s capable of validating that data and rendering the form as HTML with the data displayed in the HTML. If it’s unbound, it cannot do validation (because there’s no data to validate), but it can still render the blank form as HTML.
To bind a Form, we use the method Form.BindRequest. Method Form.BindData can be used too, when the application needs to modify the default behavior.
Example (YourName) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" "html/template" "net/http" ) func main() { http.HandleFunc("/your-name", nameHandler) http.HandleFunc("/congratulations", congratulationsHandler) panic(http.ListenAndServe(":8080", nil)) } func nameHandler(w http.ResponseWriter, req *http.Request) { nameForm := aform.Must(aform.New( aform.WithCharField(aform.Must(aform.DefaultCharField("Your name"))), )) // if this is a POST request we need to process the form data if req.Method == "POST" { // Populate the form with data from the request: nameForm.BindRequest(req) // check whether it's valid: if nameForm.IsValid() { // process the data with Form.CleanedData // ... // redirect to a new URL: http.Redirect(w, req, "/congratulations", http.StatusFound) } } _ = tmpl.ExecuteTemplate(w, "name", map[string]any{"form": nameForm}) } var tmpl = template.Must(template.New("name").Parse(tmplBody)) const tmplBody = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Name Form</title> </head> <body> <form action="/your-name" method="post"> {{ .form.AsDiv }} {{/* Add CSRF */}} <button type="submit">OK</button> </form> </body> </html>` func congratulationsHandler(w http.ResponseWriter, req *http.Request) { fmt.Fprintln(w, "Congratulations!") }
Output:
Index ¶
- Constants
- func Must[FormPtrFieldPtr FormPointerOrFieldPointer](f FormPtrFieldPtr, err error) FormPtrFieldPtr
- type AttrName
- type AttrValue
- type Attributable
- type BooleanField
- type CharField
- type ChoiceField
- type ChoiceFieldOption
- type CleanedData
- type EmailField
- type Error
- type ErrorCoderTranslator
- type Field
- func (fld *Field) AddChoiceOptions(label string, options []ChoiceFieldOption)
- func (fld *Field) AsDiv() template.HTML
- func (fld *Field) AutoID() string
- func (fld *Field) CSSClasses() string
- func (fld *Field) CustomizeError(err ErrorCoderTranslator)
- func (fld *Field) Errors() template.HTML
- func (fld *Field) HTMLName() string
- func (fld *Field) HasErrors() bool
- func (fld *Field) HasHelpText() bool
- func (fld *Field) HelpText() template.HTML
- func (fld *Field) LabelSuffix() string
- func (fld *Field) LabelTag() template.HTML
- func (fld *Field) LegendTag() template.HTML
- func (fld *Field) MarkSafe()
- func (fld *Field) Name() string
- func (fld *Field) Required() bool
- func (fld *Field) SetAttributes(attrs []Attributable)
- func (fld *Field) SetAutoID(autoID string) error
- func (fld *Field) SetDisabled()
- func (fld *Field) SetErrorCSSClass(class string)
- func (fld *Field) SetHelpText(help string)
- func (fld *Field) SetLabel(label string)
- func (fld *Field) SetLabelSuffix(labelSuffix string)
- func (fld *Field) SetLocale(locale language.Tag)
- func (fld *Field) SetNotRequired()
- func (fld *Field) SetRequiredCSSClass(class string)
- func (fld *Field) SetSanitizeFunc(update func(current SanitizationFunc) (new SanitizationFunc))
- func (fld *Field) SetValidateFunc(update func(current ValidationFunc) (new ValidationFunc))
- func (fld *Field) SetWidget(widget Widget)
- func (fld *Field) Type() FieldType
- func (fld *Field) UseFieldset() bool
- func (fld *Field) Widget() template.HTML
- type FieldOption
- func IsDisabled() FieldOption
- func IsNotRequired() FieldOption
- func IsSafe() FieldOption
- func WithAttributes(attrs []Attributable) FieldOption
- func WithChoiceOptions(options []ChoiceFieldOption) FieldOption
- func WithGroupedChoiceOptions(label string, options []ChoiceFieldOption) FieldOption
- func WithHelpText(help string) FieldOption
- func WithLabel(label string) FieldOption
- func WithWidget(widget Widget) FieldOption
- type FieldType
- type Form
- func (f *Form) AddError(field string, fieldErr error) error
- func (f *Form) AsDiv() template.HTML
- func (f *Form) BindData(data map[string][]string, langs ...string)
- func (f *Form) BindRequest(req *http.Request)
- func (f *Form) CleanedData() CleanedData
- func (f *Form) Errors() FormErrors
- func (f *Form) FieldByName(field string) (*Field, error)
- func (f *Form) Fields() []*Field
- func (f *Form) IsBound() bool
- func (f *Form) IsValid() bool
- func (f *Form) SetCleanFunc(clean func(*Form))
- type FormErrors
- type FormOption
- func DisableAutoID() FormOption
- func WithAutoID(autoID string) FormOption
- func WithBooleanField(fld *BooleanField) FormOption
- func WithCharField(fld *CharField) FormOption
- func WithChoiceField(fld *ChoiceField) FormOption
- func WithEmailField(fld *EmailField) FormOption
- func WithErrorCSSClass(class string) FormOption
- func WithLabelSuffix(labelSuffix string) FormOption
- func WithLocales(locales []language.Tag) FormOption
- func WithMultipleChoiceField(fld *MultipleChoiceField) FormOption
- func WithRequiredCSSClass(class string) FormOption
- type FormPointerOrFieldPointer
- type MultipleChoiceField
- type SanitizationFunc
- type ValidationFunc
- type Widget
Examples ¶
- Package (YourName)
- DefaultCharField (PasswordWithPlaceholder)
- DefaultChoiceField
- DefaultChoiceField (WithRadio)
- Field.AsDiv
- Field.AsDiv (WithHelpTextAndError)
- Field.CustomizeError
- Field.Errors
- Field.Errors (WithoutErrors)
- Field.HTMLName
- Field.HelpText
- Field.LabelTag
- Field.LegendTag
- Field.Name
- Field.SetLabel
- Field.SetLabelSuffix
- Field.Widget
- Form.CleanedData (AllValid)
- Form.CleanedData (WithInvalidField)
- Form.SetCleanFunc
- New (Login)
- New (NotRequiredField)
- New (Profile)
- New (YourName)
- NewCharField (PasswordWithPlaceholder)
- NewCharField (WithInitialValue)
- NewChoiceField
- NewChoiceField (WithRadio)
- WithAttributes (ClassWithErrorClass)
- WithGroupedChoiceOptions
- WithLabelSuffix
- WithWidget (PasswordInput)
- WithWidget (RadioSelect)
- WithWidget (TextArea)
Constants ¶
const ( BooleanErrorCode = "boolean" EmailErrorCode = "email" ChoiceErrorCode = "oneof" MinLengthErrorCode = "min" MaxLengthErrorCode = "max" RequiredErrorCode = "required" URLErrorCode = "url" )
Error codes of the available validations. Each validation has a code and a default message. Example: If a BooleanField value is not a boolean, the validation returns an error with the code BooleanErrorCode and the default message BooleanErrorMessageEn. Error messages can be modified with the function Field.CustomizeError.
const ( BooleanFieldType = FieldType("BooleanField") CharFieldType = FieldType("CharField") EmailFieldType = FieldType("EmailField") URLFieldType = FieldType("URLField") ChoiceFieldType = FieldType("ChoiceField") MultipleChoiceFieldType = FieldType("MultipleChoiceField") )
Field types available. Each of them has its own creation interface. For instance to create a BooleanFieldType, you can use NewBooleanField or DefaultBooleanField functions.
const ( BooleanErrorMessageEn = "Enter a valid boolean" EmailErrorMessageEn = "Enter a valid email address" ChoiceErrorMessageEn = "Invalid choice" MinLengthErrorMessageEn = "Ensure this value has at least {0} characters" MaxLengthErrorMessageEn = "Ensure this value has at most {0} characters" RequiredErrorMessageEn = "This field is required" URLErrorMessageEn = "Enter a valid URL" )
English error messages of the available validations.
const ( BooleanErrorMessageFr = "Entrez un booléen valide" EmailErrorMessageFr = "Entrez une adresse e-mail valide" ChoiceErrorMessageFr = "Choix invalide" MinLengthErrorMessageFr = "Assurez-vous que cette valeur fait au minimum {0} caractères" MaxLengthErrorMessageFr = "Assurez-vous que cette valeur fait au maximum {0} caractères" RequiredErrorMessageFr = "Ce champ est obligatoire" URLErrorMessageFr = "Entrez une URL valide" )
French error messages of the available validations.
const ( // TextInput renders as: <input type="text" ...> TextInput = Widget("TextInput") // EmailInput renders as: <input type="email" ...> EmailInput = Widget("EmailInput") // URLInput renders as: <input type="url" ...> URLInput = Widget("URLInput") // PasswordInput renders as: <input type="password" ...> PasswordInput = Widget("PasswordInput") // HiddenInput renders as: <input type="hidden" ...> HiddenInput = Widget("HiddenInput") // TextArea renders as: <textarea>...</textarea> TextArea = Widget("TextArea") // CheckboxInput renders as: <input type="checkbox" ...> CheckboxInput = Widget("CheckboxInput") // Select renders as: <select><option ...>...</select> Select = Widget("Select") // SelectMultiple renders as Select but allow multiple selection: <select multiple>...< /select> SelectMultiple = Widget("SelectMultiple") // RadioSelect is similar to Select, but rendered as a list of radio buttons within <div> tags: // <div> // <div><input type="radio" name="..."></div> // ... // </div> RadioSelect = Widget("RadioSelect") // CheckboxSelectMultiple is similar SelectMultiple, but rendered as a list of checkboxes // <div> // <div><input type="checkbox" name="..." ></div> // ... // </div> CheckboxSelectMultiple = Widget("CheckboxSelectMultiple") )
Widgets are used by the fields to handle HTML rendering. Each field as a default widget. It can be changed with WithWidget or SetWidget functions.
Variables ¶
This section is empty.
Functions ¶
func Must ¶
func Must[FormPtrFieldPtr FormPointerOrFieldPointer](f FormPtrFieldPtr, err error) FormPtrFieldPtr
Must is a helper that wraps a call to a function returning (*Form, error) or (*Field, error) and panics if the error is non-nil. It is intended for use in form creations. e.g.
var fld = Must(DefaultCharField("Name")) var f = Must(New(WithCharField(fld)))
Types ¶
type AttrValue ¶
type AttrValue interface { constraints.Integer | ~string }
AttrValue defines the HTML attribute value type
type Attributable ¶
type Attributable interface {
// contains filtered or unexported methods
}
Attributable defines a common interface for name/value HTML attributes and boolean HTML attributes.
func Attr ¶
func Attr[N AttrName, V AttrValue](name N, value V) Attributable
Attr returns an HTML attribute named name and that is equal to value. Example to add attribute placeholder="****"
Attr("placeholder", "****")
Example to add attribute maxlength="125"
Attr("maxlength", 125)
func BoolAttr ¶
func BoolAttr[N AttrName](name N) Attributable
BoolAttr returns a boolean HTML attribute named name. Example to add attribute readonly
BoolAttr("readonly")
type BooleanField ¶
type BooleanField struct { *Field // contains filtered or unexported fields }
BooleanField is a field type that validates that the given value is a valid boolean.
func DefaultBooleanField ¶
func DefaultBooleanField(name string, opts ...FieldOption) (*BooleanField, error)
DefaultBooleanField creates a boolean field with reasonable default values. The initial parameter value is false.
func NewBooleanField ¶
func NewBooleanField(name string, initial bool, opts ...FieldOption) (*BooleanField, error)
NewBooleanField creates a boolean field named name. The parameter initial is the initial value before data bounding. The default Widget is CheckboxInput. To change it, use WithWidget or SetWidget.
func (*BooleanField) Clean ¶
func (fld *BooleanField) Clean(value string) (string, []Error)
Clean returns the cleaned value. value is first sanitized and finally validated. Sanitization can be customized with Field.SetSanitizeFunc. Validation can be customized with Field.SetValidateFunc.
func (*BooleanField) EmptyValue ¶
func (fld *BooleanField) EmptyValue() string
EmptyValue returns the BooleanField empty value. The empty value is the cleaned value returned by Clean when there is no data bound to the field. A BooleanField empty value is always "off".
func (*BooleanField) MustBoolean ¶
func (fld *BooleanField) MustBoolean(value string) bool
MustBoolean returns the clean value type cast to bool. It panics if the value provided is not a valid boolean input.
type CharField ¶
type CharField struct { *Field // contains filtered or unexported fields }
CharField is a field type that doesn't do semantic validation on the given value.
func DefaultCharField ¶
func DefaultCharField(name string, opts ...FieldOption) (*CharField, error)
DefaultCharField creates a char field with reasonable default values. initial and empty parameters are the empty string. min length is 0 and max length is 256.
Example (PasswordWithPlaceholder) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField( "Password", aform.WithWidget(aform.PasswordInput), aform.WithAttributes([]aform.Attributable{aform.Attr("placeholder", "****")}))) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_password">Password</label><input type="password" name="password" id="id_password" maxlength="256" placeholder="****" required></div>
func NewCharField ¶
func NewCharField(name, initial, empty string, min, max uint, opts ...FieldOption) (*CharField, error)
NewCharField creates a char field named name. The parameter initial is the initial value before data bounding. The parameter empty is the cleaned data value when there is no data bound to the field. If the parameter min (respectively max) is not 0, it validates that the input value is longer or equal than min (respectively shorter or equal than max). Otherwise, all inputs are valid. The default Widget is TextInput. To change it, use WithWidget or SetWidget.
Example (PasswordWithPlaceholder) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.NewCharField("Password", "", "", 0, 0, aform.WithWidget(aform.PasswordInput), aform.WithAttributes([]aform.Attributable{aform.Attr("placeholder", "****")}))) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_password">Password</label><input type="password" name="password" id="id_password" placeholder="****" required></div>
Example (WithInitialValue) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.NewCharField("Your color", "white", "", 0, 0)) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_your_color">Your color</label><input type="text" name="your_color" value="white" id="id_your_color" required></div>
func (*CharField) Clean ¶
Clean returns the cleaned value. value is first sanitized and finally validated. Sanitization can be customized with Field.SetSanitizeFunc. Validation can be customized with Field.SetValidateFunc.
func (*CharField) EmptyValue ¶
EmptyValue returns the CharField empty value. The empty value is the cleaned value returned by Clean when there is no data bound to the field. To set a custom empty value use NewCharField.
type ChoiceField ¶
type ChoiceField struct { *Field // contains filtered or unexported fields }
ChoiceField is a field type that validates that the given value is one of the options listed with WithChoiceOptions or WithGroupedChoiceOptions.
func DefaultChoiceField ¶
func DefaultChoiceField(name string, opts ...FieldOption) (*ChoiceField, error)
DefaultChoiceField creates a choice field with reasonable default values. initial parameter is the empty string. To add options use WithChoiceOptions or WithGroupedChoiceOptions.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultChoiceField("Color", aform.WithChoiceOptions([]aform.ChoiceFieldOption{ {Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}, {Value: "blue", Label: "Bleu"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_color">Color</label><select name="color" id="id_color" required> <option value="red" id="id_color_0">Rouge</option> <option value="green" id="id_color_1">Vert</option> <option value="blue" id="id_color_2">Bleu</option> </select></div>
Example (WithRadio) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultChoiceField("Color", aform.WithWidget(aform.RadioSelect), aform.WithChoiceOptions([]aform.ChoiceFieldOption{ {Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}, {Value: "blue", Label: "Bleu"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div> <fieldset><legend for="id_color">Color</legend> <div id="id_color"> <label for="id_color_0"><input type="radio" name="color" value="red" id="id_color_0">Rouge</label> <label for="id_color_1"><input type="radio" name="color" value="green" id="id_color_1">Vert</label> <label for="id_color_2"><input type="radio" name="color" value="blue" id="id_color_2">Bleu</label> </div> </fieldset> </div>
func NewChoiceField ¶
func NewChoiceField(name, initial string, opts ...FieldOption) (*ChoiceField, error)
NewChoiceField creates a choice field named name. The parameter initial is the initial value before data bounding. To add options use WithChoiceOptions or WithGroupedChoiceOptions. The default Widget is Select. To change it, use WithWidget or Field.SetWidget.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.NewChoiceField("Color", "", aform.WithChoiceOptions([]aform.ChoiceFieldOption{{Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}, {Value: "blue", Label: "Bleu"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_color">Color</label><select name="color" id="id_color" required> <option value="red" id="id_color_0">Rouge</option> <option value="green" id="id_color_1">Vert</option> <option value="blue" id="id_color_2">Bleu</option> </select></div>
Example (WithRadio) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.NewChoiceField("Color", "", aform.WithWidget(aform.RadioSelect), aform.WithChoiceOptions([]aform.ChoiceFieldOption{ {Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}, {Value: "blue", Label: "Bleu"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div> <fieldset><legend for="id_color">Color</legend> <div id="id_color"> <label for="id_color_0"><input type="radio" name="color" value="red" id="id_color_0">Rouge</label> <label for="id_color_1"><input type="radio" name="color" value="green" id="id_color_1">Vert</label> <label for="id_color_2"><input type="radio" name="color" value="blue" id="id_color_2">Bleu</label> </div> </fieldset> </div>
func (*ChoiceField) Clean ¶
func (fld *ChoiceField) Clean(value string) (string, []Error)
Clean returns the cleaned value. value is first sanitized and finally validated. Sanitization can be customized with Field.SetSanitizeFunc. Validation can be customized with Field.SetValidateFunc.
func (*ChoiceField) EmptyValue ¶
func (fld *ChoiceField) EmptyValue() string
EmptyValue returns the ChoiceField empty value. The empty value is the cleaned value returned by Clean when there is no data bound to the field. A ChoiceField empty value is always the empty string "".
type ChoiceFieldOption ¶
type CleanedData ¶
CleanedData maps a field normalized name to the list of bound data after validation
func (CleanedData) Get ¶
func (d CleanedData) Get(field string) string
Get gets the first cleaned data associated with the given field. If there are no cleaned data associated with the field, Get returns the empty string. If the field accepts multiple data, use the map directly to access all of them.
func (CleanedData) Has ¶
func (d CleanedData) Has(field string) bool
Has checks whether a given field has at least one cleaned data.
type EmailField ¶
type EmailField struct { *Field // contains filtered or unexported fields }
EmailField is a field type that validates that the given value is a valid email address.
func DefaultEmailField ¶
func DefaultEmailField(name string, opts ...FieldOption) (*EmailField, error)
DefaultEmailField creates an email field with reasonable default values. initial and empty parameters are the empty string. min length is 0 and max length is 254.
func NewEmailField ¶
func NewEmailField(name, initial, empty string, min, max uint, opts ...FieldOption) (*EmailField, error)
NewEmailField creates an email field named name. The parameter initial is the initial value before data bounding. The parameter empty is the cleaned data value when there is no data bound to the field. If the parameter min (respectively max) is not 0, it validates that the input value is longer or equal than min (respectively shorter or equal than max). The default Widget is EmailInput. To change it, use WithWidget or SetWidget.
func (*EmailField) Clean ¶
func (fld *EmailField) Clean(value string) (string, []Error)
Clean returns the cleaned value. value is first sanitized and finally validated. Sanitization can be customized with Field.SetSanitizeFunc. Validation can be customized with Field.SetValidateFunc.
func (*EmailField) EmptyValue ¶
func (fld *EmailField) EmptyValue() string
EmptyValue returns the EmailField empty value. The empty value is the cleaned value returned by Clean when there is no data bound to the field. To set a custom empty value use NewEmailField.
func (*EmailField) MustEmail ¶
func (fld *EmailField) MustEmail(value string) string
MustEmail returns the clean value if the value provided is a valid email. Otherwise, it panics.
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error defines errors returned by the forms validations. It implements ErrorCoderTranslator to help the customization of existing errors or the addition of application specific errors. To customize existing validation error messages use Field.CustomizeError. To add application specific errors at the form level use SetCleanFunc and at the field level Field.SetValidateFunc.
func ErrorWrap ¶
ErrorWrap wraps an error in a validation Error. It makes possible to use any error as a validation Error.
func ErrorWrapWithCode ¶
ErrorWrapWithCode is like ErrorWrap and set or update the Error code.
type ErrorCoderTranslator ¶
ErrorCoderTranslator defines the validation errors interface.
type Field ¶
type Field struct {
// contains filtered or unexported fields
}
Field is the type grouping features shared by all field types.
func (*Field) AddChoiceOptions ¶
func (fld *Field) AddChoiceOptions(label string, options []ChoiceFieldOption)
AddChoiceOptions adds a list of ChoiceFieldOption to the Field. if the parameter label is the empty string options are not grouped together. Example without group label:
fld.AddChoiceOptions("", []ChoiceFieldOption{{Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}}) // HTML output: // <option value="red" id="id_color_0">Rouge</option> // <option value="green" id="id_color_1">Vert</option>
Example with group label:
fld.AddChoiceOptions("RG", []ChoiceFieldOption{{Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}}) // HTML output: // <optgroup label="RG"> // <option value="red" id="id_color_0_0">Rouge</option> // <option value="green" id="id_color_0_1">Vert</option> // </optgroup>
func (*Field) AsDiv ¶
AsDiv renders the field in a <div> tag.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_name">Name</label><input type="text" name="name" id="id_name" maxlength="256" required></div>
Example (WithHelpTextAndError) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fld.SetHelpText("Please, enter your name") fld.Clean("") fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_name">Name</label> <ul class="errorlist"><li id="err_0_id_name">This field is required</li></ul> <input type="text" name="name" id="id_name" maxlength="256" aria-describedby="helptext_id_name err_0_id_name" aria-invalid="true" required> <span class="helptext" id="helptext_id_name">Please, enter your name</span></div>
func (*Field) CSSClasses ¶
func (*Field) CustomizeError ¶
func (fld *Field) CustomizeError(err ErrorCoderTranslator)
CustomizeError replaces one built-in Error with err, if err ErrorCoderTranslator.Code matches one of the existing Error code. Existing Error codes are BooleanErrorCode, EmailErrorCode, ChoiceErrorCode, MinLengthErrorCode, MaxLengthErrorCode, RequiredErrorCode and URLErrorCode. If err ErrorCoderTranslator.Code is not from this list, it panics.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.NewCharField("Name", "", "", 10, 0)) fld.CustomizeError(aform.ErrorWrapWithCode(fmt.Errorf("Please, enter enough characters"), aform.MinLengthErrorCode)) fld.Clean("too_short") fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_name">Name</label> <ul class="errorlist"><li id="err_0_id_name">Please, enter enough characters</li></ul> <input type="text" name="name" value="too_short" id="id_name" minlength="10" aria-describedby="err_0_id_name" aria-invalid="true" required></div>
func (*Field) Errors ¶
Errors renders field errors in a <ul> tag with each <li> children tag containing one error. CSS class errorlist is set on the <ul> tag. Each <li> tag as a generated unique ID based on the error index and the field ID.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fld.Clean("") fmt.Println(fld.Errors()) }
Output: <ul class="errorlist"><li id="err_0_id_name">This field is required</li></ul>
Example (WithoutErrors) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fld.Clean("Paul") fmt.Printf("It renders the empty string: \"%s\"", fld.Errors()) }
Output: It renders the empty string: ""
func (*Field) HTMLName ¶
HTMLName returns the field's name transformed to be the value of the HTML name attribute.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultBooleanField("Remember me")) fmt.Println(fld.HTMLName()) }
Output: remember_me
func (*Field) HasErrors ¶
HasErrors returns true if an input is bound to the field and there is a validation error.
func (*Field) HasHelpText ¶
HasHelpText returns true if a help text has been added to the field.
func (*Field) HelpText ¶
HelpText renders the help text in a <span> tag. CSS class helptext and an ID generated from the field ID are set on the <span> tag.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fld.SetHelpText("Please, enter your name") fmt.Println(fld.HelpText()) }
Output: <span class="helptext" id="helptext_id_name">Please, enter your name</span>
func (*Field) LabelSuffix ¶
LabelSuffix returns the suffix set with SetLabelSuffix.
func (*Field) LabelTag ¶
LabelTag renders the <label> tag.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fmt.Println(fld.LabelTag()) }
Output: <label for="id_name">Name</label>
func (*Field) LegendTag ¶
LegendTag renders the <legend> tag. This tag replaces <label> tag when a <fieldset> tag is used to group together options of fields using RadioSelect widget or CheckboxSelectMultiple widget.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultCharField("Name")) fmt.Println(fld.LegendTag()) }
Output: <legend for="id_name">Name</legend>
func (*Field) MarkSafe ¶
func (fld *Field) MarkSafe()
MarkSafe marks the field label as safe for HTML. It means the label and the label suffix are no more HTML-escaped.
func (*Field) Name ¶
Name returns the name given to the field.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultBooleanField("Remember me")) fmt.Println(fld.Name()) }
Output: Remember me
func (*Field) SetAttributes ¶
func (fld *Field) SetAttributes(attrs []Attributable)
SetAttributes adds custom attributes to the Widget. See WithAttributes for details.
func (*Field) SetAutoID ¶
SetAutoID sets the string used to build the HTML ID. See WithAutoID for details on valid values.
func (*Field) SetErrorCSSClass ¶
SetErrorCSSClass sets a CSS class added to the HTML when the field has a validation error. To set the same error class to all fields in a form use WithErrorCSSClass.
func (*Field) SetHelpText ¶
SetHelpText adds a help text to the Field. Help text is not HTML-escaped.
func (*Field) SetLabel ¶
SetLabel overrides the default label of the Field. By default, the label is the name of the Field given as parameter to a Field creation function. The label is HTML-escaped. To alter more the for= attribute or to completely remove the tag <label> use SetAutoID.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultBooleanField("remember")) fld.SetLabel("Remember me") fmt.Println(fld.LabelTag()) }
Output: <label for="id_remember">Remember me</label>
func (*Field) SetLabelSuffix ¶
SetLabelSuffix sets a string appended to the label. To set the same suffix to all fields in a form use WithLabelSuffix.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must(aform.DefaultBooleanField("Remember me")) fld.SetLabelSuffix(":") fmt.Println(fld.LabelTag()) }
Output: <label for="id_remember_me">Remember me:</label>
func (*Field) SetLocale ¶
SetLocale changes the locale used by the field to translate error messages. To set the same locale to all fields in a form use WithLocales.
func (*Field) SetNotRequired ¶
func (fld *Field) SetNotRequired()
SetNotRequired sets the Field as not required. By default, all fields are required.
func (*Field) SetRequiredCSSClass ¶
SetRequiredCSSClass sets a CSS class added to the HTML if the field is required. To set the same required class to all fields in a form use WithRequiredCSSClass.
func (*Field) SetSanitizeFunc ¶
func (fld *Field) SetSanitizeFunc(update func(current SanitizationFunc) (new SanitizationFunc))
SetSanitizeFunc sets sanitization function. Parameter update is a function that itself has current sanitization function as parameter and must return the new sanitization function. Default sanitization function removes HTML elements, leading and trailing white characters. It removes as well new lines if the widget is not TextArea.
func (*Field) SetValidateFunc ¶
func (fld *Field) SetValidateFunc(update func(current ValidationFunc) (new ValidationFunc))
SetValidateFunc sets validation function. Parameter update is a function that itself has current validation function as parameter and must return the new validation function. Default validation function depends on the field type.
func (*Field) UseFieldset ¶
UseFieldset returns true if the widget used by the field
type FieldOption ¶
FieldOption describes a functional option for configuring a Field.
func IsDisabled ¶
func IsDisabled() FieldOption
IsDisabled returns a FieldOption that sets the Field as disabled.
func IsNotRequired ¶
func IsNotRequired() FieldOption
IsNotRequired returns a FieldOption that sets the Field as not required. By default, all fields are required.
func IsSafe ¶
func IsSafe() FieldOption
IsSafe returns a FieldOption that sets the Field as HTML safe. When a field is marked as safe, its label and label suffix are not HTML-escaped.
func WithAttributes ¶
func WithAttributes(attrs []Attributable) FieldOption
WithAttributes returns a FieldOption that adds custom attributes to the Widget. For all the attributes but the class attribute, values set with this function override the values set by any other logic. If the class attribute is set, the error class set with the function SetErrorCSSClass is concatenated at the beginning. Three attribute names panic: type, name and value. To change the type, use a different Field and/or set a different Widget on an existing Field. To change the name attribute, set a different name to the Field when you create it. To change the value attribute, set an initial value when you create the field or bind values with BindRequest or BindData functions.
Example (ClassWithErrorClass) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithRequiredCSSClass("required"), aform.WithErrorCSSClass("error"), aform.WithCharField(aform.Must(aform.DefaultCharField( "Name", aform.WithAttributes([]aform.Attributable{aform.Attr("class", "big blue")}), ))), )) // Bind empty data. As the field is required, // it will make IsValid == false and add error to the HTML generated. f.BindData(map[string][]string{}) // Run the form validation f.IsValid() fmt.Println(f.AsDiv()) }
Output: <div class="required error"><label class="required" for="id_name">Name</label> <ul class="errorlist"><li id="err_0_id_name">This field is required</li></ul> <input type="text" name="name" class="error big blue" id="id_name" maxlength="256" aria-describedby="err_0_id_name" aria-invalid="true" required></div>
func WithChoiceOptions ¶
func WithChoiceOptions(options []ChoiceFieldOption) FieldOption
WithChoiceOptions returns a FieldOption that adds a list of ChoiceFieldOption to the Field. This option is used only by fields presenting a list of choices like ChoiceField and MultipleChoiceField.
func WithGroupedChoiceOptions ¶
func WithGroupedChoiceOptions(label string, options []ChoiceFieldOption) FieldOption
WithGroupedChoiceOptions returns a FieldOption that adds a list of ChoiceFieldOption grouped together in a <optgroup> tag. Parameter label is the value of the <optgroup> attribute label. This option is used only by fields presenting a list of choices like ChoiceField and MultipleChoiceField.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultChoiceField("Color", aform.WithGroupedChoiceOptions("RGB", []aform.ChoiceFieldOption{ {Value: "red", Label: "Rouge"}, {Value: "green", Label: "Vert"}, {Value: "blue", Label: "Bleu"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_color">Color</label><select name="color" id="id_color" required> <optgroup label="RGB"> <option value="red" id="id_color_0_0">Rouge</option> <option value="green" id="id_color_0_1">Vert</option> <option value="blue" id="id_color_0_2">Bleu</option> </optgroup> </select></div>
func WithHelpText ¶
func WithHelpText(help string) FieldOption
WithHelpText returns a FieldOption that adds a help text to the Field. Help text is not HTML-escaped.
func WithLabel ¶
func WithLabel(label string) FieldOption
WithLabel returns a FieldOption that overrides the default label of the Field.
func WithWidget ¶
func WithWidget(widget Widget) FieldOption
WithWidget returns a FieldOption that changes the Widget of the Field.
Example (PasswordInput) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultCharField( "Password", aform.WithWidget(aform.PasswordInput), ), ) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_password">Password</label><input type="password" name="password" id="id_password" maxlength="256" required></div>
Example (RadioSelect) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultChoiceField( "Color", aform.WithWidget(aform.RadioSelect), aform.WithChoiceOptions([]aform.ChoiceFieldOption{ {Value: "red", Label: "Red"}, {Value: "green", Label: "Green"}, {Value: "blue", Label: "Blue"}, }), ), ) fmt.Println(fld.AsDiv()) }
Output: <div> <fieldset><legend for="id_color">Color</legend> <div id="id_color"> <label for="id_color_0"><input type="radio" name="color" value="red" id="id_color_0">Red</label> <label for="id_color_1"><input type="radio" name="color" value="green" id="id_color_1">Green</label> <label for="id_color_2"><input type="radio" name="color" value="blue" id="id_color_2">Blue</label> </div> </fieldset> </div>
Example (TextArea) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { fld := aform.Must( aform.DefaultCharField( "Description", aform.WithWidget(aform.TextArea), ), ) fmt.Println(fld.AsDiv()) }
Output: <div><label for="id_description">Description</label><textarea name="description" id="id_description" maxlength="256" required> </textarea></div>
type Form ¶
type Form struct {
// contains filtered or unexported fields
}
Form represents a form.
func New ¶
func New(opts ...FormOption) (*Form, error)
New returns a Form.
Example (Login) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithEmailField(aform.Must(aform.DefaultEmailField("Email"))), aform.WithCharField(aform.Must(aform.DefaultCharField("Password", aform.WithWidget(aform.PasswordInput)))), aform.WithBooleanField(aform.Must(aform.DefaultBooleanField("Remember me"))), )) fmt.Println(f.AsDiv()) }
Output: <div><label for="id_email">Email</label><input type="email" name="email" id="id_email" maxlength="254" required></div> <div><label for="id_password">Password</label><input type="password" name="password" id="id_password" maxlength="256" required></div> <div><label for="id_remember_me">Remember me</label><input type="checkbox" name="remember_me" id="id_remember_me" required></div>
Example (NotRequiredField) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { // Create a form with two not required fields nicknameFld, _ := aform.NewCharField("Nickname", "", "nickname_default", 0, 0, aform.IsNotRequired()) emailFld, _ := aform.NewEmailField("Email", "", "catchall@domain.com", 0, 0, aform.IsNotRequired()) f, err := aform.New( aform.WithCharField(nicknameFld), aform.WithEmailField(emailFld), ) if err != nil { panic("invalid form") } // Simulate an empty form post. Bind nil f.BindData(nil) // IsValid is true because fields are not required if !f.IsValid() { panic("form must be valid") } fmt.Println(f.CleanedData().Get("nickname")) fmt.Println(f.CleanedData().Get("email")) }
Output: nickname_default catchall@domain.com
Example (Profile) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f, err := aform.New( aform.WithCharField(aform.Must(aform.DefaultCharField("Username"))), aform.WithChoiceField(aform.Must(aform.DefaultChoiceField("Avatar", aform.WithChoiceOptions([]aform.ChoiceFieldOption{ {Value: "apple", Label: "Apple"}, {Value: "orange", Label: "Orange"}, {Value: "strawberry", Label: "Strawberry"}, })))), aform.WithChoiceField(aform.Must(aform.DefaultChoiceField( "Color", aform.WithGroupedChoiceOptions("Basic", []aform.ChoiceFieldOption{ {Value: "red", Label: "Red"}, {Value: "green", Label: "Green"}, {Value: "blue", Label: "Blue"}, }), aform.WithGroupedChoiceOptions("Fancy", []aform.ChoiceFieldOption{ {Value: "orange", Label: "Orange"}, {Value: "purple", Label: "Purple"}, {Value: "pink", Label: "Pink"}, }), )), ), ) if err != nil { panic("invalid form") } fmt.Println(f.AsDiv()) }
Output: <div><label for="id_username">Username</label><input type="text" name="username" id="id_username" maxlength="256" required></div> <div><label for="id_avatar">Avatar</label><select name="avatar" id="id_avatar" required> <option value="apple" id="id_avatar_0">Apple</option> <option value="orange" id="id_avatar_1">Orange</option> <option value="strawberry" id="id_avatar_2">Strawberry</option> </select></div> <div><label for="id_color">Color</label><select name="color" id="id_color" required> <optgroup label="Basic"> <option value="red" id="id_color_0_0">Red</option> <option value="green" id="id_color_0_1">Green</option> <option value="blue" id="id_color_0_2">Blue</option> </optgroup> <optgroup label="Fancy"> <option value="orange" id="id_color_1_0">Orange</option> <option value="purple" id="id_color_1_1">Purple</option> <option value="pink" id="id_color_1_2">Pink</option> </optgroup> </select></div>
Example (YourName) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { nameForm := aform.Must(aform.New( aform.WithCharField(aform.Must(aform.DefaultCharField("Your name"))), )) fmt.Println(nameForm.AsDiv()) }
Output: <div><label for="id_your_name">Your name</label><input type="text" name="your_name" id="id_your_name" maxlength="256" required></div>
func (*Form) AddError ¶
AddError adds an error to the field named field. An error can be added after the form has been validated. AddError can be used in the form clean function set with SetCleanFunc to perform Form level validation. If err implements ErrorCoderTranslator, error message will be translated according to the language automatically identified by BindRequest or according to the language given to BindData.
func (*Form) AsDiv ¶
AsDiv renders the form as a list of <div> tags, with each <div> containing one field.
func (*Form) BindData ¶
BindData binds data to the Form. After a first binding, following bindings are ignored. If you want to bind new data, you should create another identical Form to do it. Data is bound but not validated. Validation is done when IsValid, CleanedData or Errors are called.
func (*Form) BindRequest ¶
BindRequest binds req form data to the Form. After a first binding, following bindings are ignored. If you want to bind new data, you should create another identical Form to do it. Data is bound but not validated. Validation is done when IsValid, CleanedData or Errors are called. Error messages are localized according to Accept-Language header. To modify this behavior use directly BindData.
func (*Form) CleanedData ¶
func (f *Form) CleanedData() CleanedData
CleanedData returns cleaned data validated from Form inputs. It does Form validation if it is not already done. If a field validation returns an error it doesn't appear in CleanedData.
Example (AllValid) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithEmailField(aform.Must(aform.DefaultEmailField("Email"))), aform.WithCharField(aform.Must(aform.DefaultCharField("Password", aform.WithWidget(aform.PasswordInput)))), )) f.BindData(map[string][]string{"email": {"john.doe@gmail.com"}, "password": {"Password123"}}) f.IsValid() fmt.Printf("email: \"%s\"\n", f.CleanedData().Get("email")) fmt.Printf("password: \"%s\"\n", f.CleanedData().Get("password")) }
Output: email: "john.doe@gmail.com" password: "Password123"
Example (WithInvalidField) ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithEmailField(aform.Must(aform.DefaultEmailField("Email"))), aform.WithCharField(aform.Must(aform.DefaultCharField("Password", aform.WithWidget(aform.PasswordInput)))), )) f.BindData(map[string][]string{"email": {"invalid email"}, "password": {"Password123"}}) f.IsValid() fmt.Printf("email: \"%s\"\n", f.CleanedData().Get("email")) fmt.Printf("password: \"%s\"\n", f.CleanedData().Get("password")) fmt.Printf("email error: \"%s\"\n", f.Errors().Get("email")) fmt.Printf("password error: \"%s\"\n", f.Errors().Get("password")) }
Output: email: "" password: "Password123" email error: "Enter a valid email address" password error: ""
func (*Form) Errors ¶
func (f *Form) Errors() FormErrors
Errors returns errors happened during validation of form inputs. It does Form validation if it is not already done. If a field input is valid it doesn't appear in FormErrors.
func (*Form) FieldByName ¶
FieldByName returns the field with the normalized name field. If there is no Field matching, an error is returned.
func (*Form) IsBound ¶
IsBound returns true if the form is already bound to data with BindRequest or BindData.
func (*Form) IsValid ¶
IsValid returns true if all the fields' validation return no error. It does Form validation if it is not already done.
func (*Form) SetCleanFunc ¶
SetCleanFunc sets a clean function to do validation at the form level.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithEmailField(aform.Must(aform.DefaultEmailField("email1", aform.WithLabel("Email")))), aform.WithEmailField(aform.Must(aform.DefaultEmailField("email2", aform.WithLabel("Email verification")))), )) f.SetCleanFunc(func(form *aform.Form) { if !form.IsValid() { return } data := form.CleanedData() if data.Get("email1") != data.Get("email2") { err := fmt.Errorf("Emails must be the same") _ = form.AddError("email1", err) _ = form.AddError("email2", err) } }) f.BindData(map[string][]string{"email1": []string{"g@gmail.com"}, "email2": []string{"h@gmail.com"}}) // Run the form validation f.IsValid() fmt.Println(f.AsDiv()) }
Output: <div><label for="id_email1">Email</label> <ul class="errorlist"><li id="err_0_id_email1">Emails must be the same</li></ul> <input type="email" name="email1" value="g@gmail.com" id="id_email1" maxlength="254" aria-describedby="err_0_id_email1" aria-invalid="true" required></div> <div><label for="id_email2">Email verification</label> <ul class="errorlist"><li id="err_0_id_email2">Emails must be the same</li></ul> <input type="email" name="email2" value="h@gmail.com" id="id_email2" maxlength="254" aria-describedby="err_0_id_email2" aria-invalid="true" required></div>
type FormErrors ¶
FormErrors maps a field normalized name to the list of errors after validation
func (FormErrors) Get ¶
func (e FormErrors) Get(field string) Error
Get gets the first error associated with the given field. If there are no errors associated with the field, Get returns an empty Error with its code and message equal empty string. To access multiple errors, use the map directly.
func (FormErrors) Has ¶
func (e FormErrors) Has(field string) bool
Has checks whether a given field has an error.
type FormOption ¶
FormOption describes a functional option for configuring a Form.
func DisableAutoID ¶
func DisableAutoID() FormOption
DisableAutoID returns a FormOption that deactivates the automatic ID creation for all the fields. When auto ID is disabled fields don't have a label tag unless a field override the auto ID behaviour with Field.SetAutoID.
func WithAutoID ¶
func WithAutoID(autoID string) FormOption
WithAutoID returns a FormOption that changes how HTML IDs are automatically built for all the fields. Correct values are either an empty string or a string containing one verb '%s'. An empty string deactivates auto ID. It's equivalent as using DisableAutoID. With a string containing one verb '%s' it's possible to customize auto ID. e.g. "id_%s"
A non-empty string without a verb '%s' is invalid.
func WithBooleanField ¶
func WithBooleanField(fld *BooleanField) FormOption
WithBooleanField returns a FormOption that adds the BooleanField fld to the list of fields.
func WithCharField ¶
func WithCharField(fld *CharField) FormOption
WithCharField returns a FormOption that adds the CharField fld to the list of fields.
func WithChoiceField ¶
func WithChoiceField(fld *ChoiceField) FormOption
WithChoiceField returns a FormOption that adds the ChoiceField fld to the list of fields.
func WithEmailField ¶
func WithEmailField(fld *EmailField) FormOption
WithEmailField returns a FormOption that adds the EmailField fld to the list of fields.
func WithErrorCSSClass ¶
func WithErrorCSSClass(class string) FormOption
WithErrorCSSClass returns a FormOption that adds class to CSS classes when a field validation returns an error. CSS class is added to all fields that have an error after validation.
func WithLabelSuffix ¶
func WithLabelSuffix(labelSuffix string) FormOption
WithLabelSuffix returns a FormOption that set a suffix to labels. Label suffix is added to all fields.
Example ¶
package main import ( "fmt" "github.com/roleupjobboard/aform" ) func main() { f := aform.Must(aform.New( aform.WithLabelSuffix(":"), aform.WithEmailField(aform.Must(aform.DefaultEmailField("email"))), aform.WithCharField(aform.Must(aform.DefaultCharField("password", aform.WithWidget(aform.PasswordInput)))), )) fmt.Println(f.AsDiv()) }
Output: <div><label for="id_email">email:</label><input type="email" name="email" id="id_email" maxlength="254" required></div> <div><label for="id_password">password:</label><input type="password" name="password" id="id_password" maxlength="256" required></div>
func WithLocales ¶
func WithLocales(locales []language.Tag) FormOption
WithLocales returns a FormOption that sets the list of locales used to translate error messages. Default locale is "en".
func WithMultipleChoiceField ¶
func WithMultipleChoiceField(fld *MultipleChoiceField) FormOption
WithMultipleChoiceField returns a FormOption that adds the MultipleChoiceField fld to the list of fields.
func WithRequiredCSSClass ¶
func WithRequiredCSSClass(class string) FormOption
WithRequiredCSSClass returns a FormOption that adds class to CSS classes when a field is required. CSS class is added to all required fields.
type FormPointerOrFieldPointer ¶
type FormPointerOrFieldPointer interface { *Form | *BooleanField | *EmailField | *CharField | *ChoiceField | *MultipleChoiceField }
FormPointerOrFieldPointer defines a union type to allow the usage of the helper function Must with forms and all fields types.
type MultipleChoiceField ¶
type MultipleChoiceField struct { *Field // contains filtered or unexported fields }
MultipleChoiceField is a field type that validates that the given values are contained in options listed with WithChoiceOptions or WithGroupedChoiceOptions.
func DefaultMultipleChoiceField ¶
func DefaultMultipleChoiceField(name string, opts ...FieldOption) (*MultipleChoiceField, error)
DefaultMultipleChoiceField creates a choice field with reasonable default values. initial parameter is an empty slice. To add options use WithChoiceOptions or WithGroupedChoiceOptions.
func NewMultipleChoiceField ¶
func NewMultipleChoiceField(name string, initials []string, opts ...FieldOption) (*MultipleChoiceField, error)
NewMultipleChoiceField creates a choice field named name. It allows multiple values to be selected. The parameter initials is the list of initial values before data bounding. To add options use WithChoiceOptions or WithGroupedChoiceOptions. The default Widget is SelectMultiple. To change it, use WithWidget or Field.SetWidget.
func (*MultipleChoiceField) Clean ¶
func (fld *MultipleChoiceField) Clean(values []string) ([]string, []Error)
Clean returns the slice of cleaned value. values are first sanitized and finally validated. Sanitization can be customized with Field.SetSanitizeFunc. Validation can be customized with Field.SetValidateFunc.
func (*MultipleChoiceField) EmptyValue ¶
func (fld *MultipleChoiceField) EmptyValue() []string
EmptyValue returns the MultipleChoiceField empty value. The empty value is the cleaned value returned by Clean when there is no data bound to the field. A MultipleChoiceField empty value is always an empty slice.
type SanitizationFunc ¶
SanitizationFunc defines a function to sanitize a Field.
type ValidationFunc ¶
ValidationFunc defines a function to validate a Field.
Source Files ¶
- attr.go
- autoid.go
- booleanfield.go
- charfield.go
- choicefield.go
- choicefieldoption.go
- doc.go
- emailfield.go
- error.go
- field.go
- fieldcustomizer.go
- fieldinitializer.go
- fieldreader.go
- fieldrenderer.go
- form.go
- formvalidation.go
- internal.go
- multiplechoicefield.go
- sanitization.go
- template.go
- templateattr.go
- translation.go
- validation.go
- widget.go