Skip to main content

Forms & Validation

Use Form with TextFormField for validated text input. The form tracks all fields and provides Validate(), Save(), and Reset() methods.

Basic Usage

type loginState struct {
core.StateBase
email string
password string
}

func (s *loginState) Build(ctx core.BuildContext) core.Widget {
return widgets.Form{
Autovalidate: true,
Child: loginForm{state: s},
}
}

// Separate widget to access FormOf(ctx)
type loginForm struct {
core.StatelessBase
state *loginState
}

func (f loginForm) Build(ctx core.BuildContext) core.Widget {
form := widgets.FormOf(ctx)

return widgets.Column{
CrossAxisAlignment: widgets.CrossAxisAlignmentStretch,
MainAxisSize: widgets.MainAxisSizeMin,
Children: []core.Widget{
// Themed form field (recommended)
theme.TextFormFieldOf(ctx).
WithLabel("Email").
WithPlaceholder("you@example.com").
WithValidator(func(value string) string {
if value == "" {
return "Email is required"
}
if !strings.Contains(value, "@") {
return "Please enter a valid email"
}
return ""
}).
WithOnSaved(func(value string) {
f.state.email = value
}),
widgets.VSpace(16),

theme.TextFormFieldOf(ctx).
WithLabel("Password").
WithPlaceholder("Enter password").
WithObscure(true).
WithValidator(func(value string) string {
if len(value) < 8 {
return "Password must be at least 8 characters"
}
return ""
}).
WithOnSaved(func(value string) {
f.state.password = value
}),
widgets.VSpace(24),

theme.ButtonOf(ctx, "Submit", func() {
if form.Validate() {
form.Save()
// Use f.state.email and f.state.password
}
}),
},
}
}

Form Methods

MethodDescription
Validate()Run validators on all fields, returns bool
Save()Call OnSaved for all fields
Reset()Reset all fields to initial values

TextFormField Options

FieldDescription
TextFieldBase TextField for theme styling (use with theme.TextFieldOf)
ControllerText editing controller (if nil, an internal one is created)
InitialValueStarting value when no Controller is provided
ValidatorReturns error message or empty string if valid
OnSavedCalled when the form is saved
OnChangedCalled when the field value changes
OnSubmittedCalled when the user submits
OnEditingCompleteCalled with current text when editing is complete
AutovalidateValidate on every change
LabelLabel text shown above the field
PlaceholderPlaceholder text shown when empty
HelperTextHelper text shown below the field (hidden when validation fails)
ObscureHide text (for passwords)
AutocorrectEnable auto-correction
DisabledReject input and skip validation when true
KeyboardTypeKeyboard type (KeyboardTypeEmail, KeyboardTypeNumber, etc.)
InputActionAction button (TextInputActionNext, TextInputActionDone, etc.)
LabelStyleStyle for the label text above the field
HelperStyleStyle for helper/error text below the field
ErrorColorColor for error text and border when validation fails

Themed vs Explicit

// Themed (recommended) - inherits colors, typography from theme
theme.TextFormFieldOf(ctx).
WithLabel("Email").
WithValidator(validateEmail)

// Explicit - must provide all visual properties
widgets.TextFormField{
Label: "Email",
LabelStyle: graphics.TextStyle{Color: labelColor, FontSize: 14},
HelperStyle: graphics.TextStyle{Color: helperColor, FontSize: 12},
ErrorColor: errorColor,
Validator: validateEmail,
}

Next Steps