diff --git a/content/docs/constraints/_index.md b/content/docs/constraints/_index.md
index 3d5e904..8783a98 100644
--- a/content/docs/constraints/_index.md
+++ b/content/docs/constraints/_index.md
@@ -1,6 +1,126 @@
---
linkTitle: Constraints
title: Constraints
-weight: 4
+weight: 5
---
+The validation is designed to validate data against constraints.
+
+## Import
+
+```golang
+import (
+ "gitnet.fr/deblan/go-form/validation"
+)
+```
+
+## Constraints
+
+### Length
+
+Validate the length of an array, a slice or a string
+
+```golang
+c := validation.NewLength()
+
+// Define minimum
+c.WithMin(1)
+
+// Define minimum
+c.WithMax(100)
+
+// Define min and max
+// Equivalent to c.WithMin(50).WithMax(50)
+c.WithExact(50)
+```
+
+### Mail
+
+```golang
+validation.NewMail()
+```
+
+### Not blank
+
+```golang
+validation.NewNotBlank()
+```
+
+### Range
+
+Validate a number
+
+```golang
+c := validation.NewRange()
+
+// Define minimum
+c.WithMin(1)
+
+// Define minimum
+c.WithMax(100)
+
+// Define min and max
+// Equivalent to c.WithMin(1).WithMax(100)
+c.WithRange(1, 100)
+```
+
+### Regex
+
+Validate a string with a regex
+
+```golang
+c := validation.NewRegex(`expression`)
+
+// The value must match
+c.MustMatch()
+
+// The value must not match
+c.MustNotMatch()
+```
+
+## Custom constraint
+
+Use case: you want to validate that the data is an even number.
+
+```golang
+package validation
+
+import (
+ "strconv"
+
+ v "gitnet.fr/deblan/go-form/validation"
+)
+
+// Define a struct
+type IsEven struct {
+ Message string
+ TypeErrorMessage string
+}
+
+// Create a factory
+func NewIsEven() IsEven {
+ return IsEven{
+ Message: "This value is not an even number.",
+ TypeErrorMessage: "This value can not be processed.",
+ }
+}
+
+// Implement the validation
+func (c IsEven) Validate(data any) []Error {
+ errors := []Error{}
+
+ // The constraint should not validate an empty data
+ if len(v.NewNotBlank().Validate(data)) == 0 {
+ i, err := strconv.Atoi(data.(string))
+
+ if err != nil {
+ errors = append(errors, Error(c.TypeErrorMessage))
+ } else if i%2 != 0 {
+ errors = append(errors, Error(c.Message))
+ }
+ }
+
+ return errors
+}
+```
+
diff --git a/content/docs/fields/_index.md b/content/docs/fields/_index.md
index c2641b7..a32a920 100644
--- a/content/docs/fields/_index.md
+++ b/content/docs/fields/_index.md
@@ -4,40 +4,299 @@ title: Fields
weight: 4
---
-The documentation of field is realised with this program.
+A field represents a field in a form.
-```golang {hl_lines=[12,13]}
-import (
- "bytes"
- "fmt"
- "html/template"
+## Struct
- "gitnet.fr/deblan/go-form/form"
- "gitnet.fr/deblan/go-form/theme"
-)
-
-func main() {
- myForm := form.NewForm(
- // the documented field here
- // form.NewField...
- ).
- WithName("form").
- End()
-
- render := theme.NewRenderer(theme.Html5)
- tpl, _ := template.New("example").Funcs(render.FuncMap()).Parse(`{{- form .Form -}}`)
-
- var buffer bytes.Buffer
-
- tpl.Execute(&buffer, map[string]any{
- "Form": myForm,
- })
-
- fmt.Print(buffer.String())
+```golang
+type Field struct {
+ Name string
+ Widget string
+ Data any
+ Options []*Option
+ Children []*Field
+ Constraints []validation.Constraint
+ Errors []validation.Error
+ PrepareView func() map[string]any
+ BeforeMount func(data any) (any, error)
+ BeforeBind func(data any) (any, error)
+ Validate func(f *Field) bool
+ IsSlice bool
+ IsFixedName bool
+ Form *Form
+ Parent *Field
}
```
-## Common options
+## Fields
+
+```golang
+func NewField(name, widget string) *Field
+```
+
+Generates a new field with default properties It should not be used directly but inside function like in form.NewFieldText
+
+### Checkbox
+
+```golang
+func NewFieldCheckbox(name string) *Field
+```
+
+Generates an input[type=checkbox]
+
+### Choice
+
+```golang
+func NewFieldChoice(name string) *Field
+```
+
+Generates inputs (checkbox or radio) or selects
+
+### Csrf
+
+```golang
+func NewFieldCsrf(name string) *Field
+```
+
+### Date
+
+```golang
+func NewFieldDate(name string) *Field
+```
+
+Generates an input[type=date] with default transformers
+
+### Datetime
+
+```golang
+func NewFieldDatetime(name string) *Field
+```
+
+Generates an input[type=datetime] with default transformers
+
+### DatetimeLocal
+
+```golang
+func NewFieldDatetimeLocal(name string) *Field
+```
+
+Generates an input[type=datetime-local] with default transformers
+
+### Hidden
+
+```golang
+func NewFieldHidden(name string) *Field
+```
+
+Generates an input[type=hidden]
+
+### Mail
+
+```golang
+func NewFieldMail(name string) *Field
+```
+
+Generates an input[type=email]
+
+### Number
+
+```golang
+func NewFieldNumber(name string) *Field
+```
+
+Generates an input[type=number] with default transformers
+
+### Password
+
+```golang
+func NewFieldPassword(name string) *Field
+```
+
+Generates an input[type=password]
+
+### Range
+
+```golang
+func NewFieldRange(name string) *Field
+```
+
+Generates an input[type=range]
+
+### Sub Form
+
+```golang
+func NewFieldSubForm(name string) *Field
+```
+
+Alias:
+
+```golang
+func NewSubForm(name string) *Field
+```
+
+Generates a sub form
+
+### Text
+
+```golang
+func NewFieldText(name string) *Field
+```
+
+Generates an input[type=text]
+
+### Textarea
+
+```golang
+func NewFieldTextarea(name string) *Field
+```
+
+Generates a textarea
+
+### Time
+
+```golang
+func NewFieldTime(name string) *Field
+```
+
+Generates an input[type=time] with default transformers
+
+### Submit
+
+```golang
+func NewSubmit(name string) *Field
+```
+
+Generates an input[type=submit]
+
+## Methods
+
+### Add
+
+```golang
+func (f *Field) Add(children ...*Field) *Field
+```
+
+Appends children
+
+### Bind
+
+```golang
+func (f *Field) Bind(data map[string]any, key *string) error
+```
+
+Bind the data into the given map
+
+### GetChild
+
+```golang
+func (f *Field) GetChild(name string) *Field
+```
+
+Returns a child using its name
+
+### GetId
+
+```golang
+func (f *Field) GetId() string
+```
+
+Computes the id of the field
+
+### GetName
+
+```golang
+func (f *Field) GetName() string
+```
+
+Computes the name of the field
+
+### GetOption
+
+```golang
+func (f *Field) GetOption(name string) *Option
+```
+
+Returns an option using its name
+
+### HasChild
+
+```golang
+func (f *Field) HasChild(name string) bool
+```
+
+Checks if the field contains a child using its name
+
+### HasOption
+
+```golang
+func (f *Field) HasOption(name string) bool
+```
+
+Checks if the field contains an option using its name
+
+### Mount
+
+```golang
+func (f *Field) Mount(data any) error
+```
+
+Populates the field with data
+
+### ResetErrors
+
+```golang
+func (f *Field) ResetErrors() *Field
+```
+
+Resets the field errors
+
+### WithBeforeBind
+
+```golang
+func (f *Field) WithBeforeBind(callback func(data any) (any, error)) *Field
+```
+
+Sets a transformer applied to the data of a field before defining it in a structure
+
+### WithBeforeMount
+
+```golang
+func (f *Field) WithBeforeMount(callback func(data any) (any, error)) *Field
+```
+
+Sets a transformer applied to the structure data before displaying it in a field
+
+### WithConstraints
+
+```golang
+func (f *Field) WithConstraints(constraints ...validation.Constraint) *Field
+```
+
+Appends constraints
+
+### WithData
+
+```golang
+func (f *Field) WithData(data any) *Field
+```
+
+Sets data the field
+
+### WithFixedName
+
+```golang
+func (f *Field) WithFixedName() *Field
+```
+
+Sets that the name of the field is not computed
+
+### WithOptions
+
+```golang
+func (f *Field) WithOptions(options ...*Option) *Field
+```
+
+#### Common options
| Name | type | description | Info |
| ---- | ---- | ---- | ---- |
@@ -47,3 +306,13 @@ func main() {
| `label` | `string` | The label of the field | Usually show before the field |
| `label_attr` | `map[string]string` | List of extra attributes of the label | |
| `help` | `string` | Helper of the field | |
+
+Appends options to the field
+
+### WithSlice
+
+```golang
+func (f *Field) WithSlice() *Field
+```
+
+Sets that the field represents a data slice
diff --git a/content/docs/fields/button.md b/content/docs/fields/button.md
deleted file mode 100644
index e69de29..0000000
diff --git a/content/docs/fields/input/date.md b/content/docs/fields/input/date.md
deleted file mode 100644
index 6555c18..0000000
--- a/content/docs/fields/input/date.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-linkTitle: Date
-title: Date
----
-
diff --git a/content/docs/fields/input/datetime.md b/content/docs/fields/input/datetime.md
deleted file mode 100644
index bc33e0a..0000000
--- a/content/docs/fields/input/datetime.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-linkTitle: Datetime
-title: Datetime
----
-
diff --git a/content/docs/fields/input/hidden.md b/content/docs/fields/input/hidden.md
deleted file mode 100644
index 9293d96..0000000
--- a/content/docs/fields/input/hidden.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-linkTitle: Hidden
-title: Hidden
-weight: 2
----
-
diff --git a/content/docs/fields/input/mail.md b/content/docs/fields/input/mail.md
deleted file mode 100644
index 7a7f44b..0000000
--- a/content/docs/fields/input/mail.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-linkTitle: Mail
-title: Mail
----
-
-
diff --git a/content/docs/fields/input/number.md b/content/docs/fields/input/number.md
deleted file mode 100644
index 89ae187..0000000
--- a/content/docs/fields/input/number.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-linkTitle: Number
-title: Number
----
-
-
diff --git a/content/docs/fields/input/password.md b/content/docs/fields/input/password.md
deleted file mode 100644
index 37c761f..0000000
--- a/content/docs/fields/input/password.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-linkTitle: Password
-title: Password
----
-
-
diff --git a/content/docs/fields/input/range.md b/content/docs/fields/input/range.md
deleted file mode 100644
index a085305..0000000
--- a/content/docs/fields/input/range.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-linkTitle: Range
-title: Range
----
-
-
diff --git a/content/docs/fields/input/text.md b/content/docs/fields/input/text.md
deleted file mode 100644
index 5badb2b..0000000
--- a/content/docs/fields/input/text.md
+++ /dev/null
@@ -1,50 +0,0 @@
----
-linkTitle: Text
-title: Text
-weight: 1
----
-
-## Basic example
-
-{{< tabs items="GO,Result" >}}
- {{< tab >}}
-```golang
-form.NewFieldText("Name")
-```
- {{< /tab >}}
- {{< tab >}}
-```html
-
-```
- {{< /tab >}}
-{{< /tabs >}}
-
-## Fully featured example
-
-{{< tabs items="GO,Result" >}}
- {{< tab >}}
-```golang
-form.NewFieldText("Name").
- WithOptions(
- form.NewOption("label", "Name"),
- form.NewOption("required", true),
- form.NewOption("attr", map[string]string{"data-foo": "foo"}),
- form.NewOption("row_attr", map[string]string{"data-bar": "bar"}),
- )
-```
- {{< /tab >}}
- {{< tab >}}
-```html
-
-```
- {{< /tab >}}
-{{< /tabs >}}
diff --git a/content/docs/fields/input/time.md b/content/docs/fields/input/time.md
deleted file mode 100644
index e084646..0000000
--- a/content/docs/fields/input/time.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-linkTitle: Time
-title: Time
----
-
diff --git a/content/docs/fields/textarea.md b/content/docs/fields/textarea.md
deleted file mode 100644
index e69de29..0000000