Fields
Fields are the building blocks of a form. Lattice ships Text input, Textarea, Select, Choice, Checkbox, Toggle, Date input, Time input, Date time input, Number input, Password input, Hidden input, File upload, Rich editor, Repeater, and Builder — and you can add your own. Each field type has its own page for the options unique to it; this page covers the options every field shares.
The submit button is not a field: the form renders it for you from ->submitLabel(). See
Overview for how to customize or replace it.
For validation and conditional behavior — which also apply to every field — see Validation and Conditional fields.
The options below extend the base Field class, so they work the same on every field. The examples
use TextInput, but the methods are identical everywhere.
make() takes the field name and an optional label. Pass the label as the second argument, or
set it later with ->label(). Omit it and the field renders without a visible label.
TextInput::make('name', 'Team name');
TextInput::make('name')->label('Team name');Default value
Section titled “Default value”->value() seeds the field with a starting value. On a form bound to a record, the record’s
value wins; otherwise this default is used.
TextInput::make('name', 'Team name') ->value('Acme Inc')- autoComplete:null
- autoFocus:false
- columnWidth:"md"
- conditions:null
- copyable:false
- dependsOnAny:false
- dependsOnKeys:null
- disabled:false
- editablePrefill:false
- helperText:null
- label:"Team name"
- labelAction:null
- name:"name"
- placeholder:null
- prefillRefreshOn:null
- prefillResetOn:null
- prefix:null
- prefixFieldName:null
- readOnly:false
- required:false
- suffix:null
- suffixFieldName:null
- tabIndex:null
- tooltip:null
- type:null
- value:"Acme Inc"
Helper text
Section titled “Helper text”->helperText() adds a line of descriptive text beneath the field; ->hint() is an alias that reads
more naturally for short tips. It renders muted, below the input and above any validation message.
TextInput::make('slug', 'Slug') ->helperText('Used in the public URL for your team.')- autoComplete:null
- autoFocus:false
- columnWidth:"md"
- conditions:null
- copyable:false
- dependsOnAny:false
- dependsOnKeys:null
- disabled:false
- editablePrefill:false
- helperText:"Used in the public URL for your team."
- label:"Slug"
- labelAction:null
- name:"slug"
- placeholder:null
- prefillRefreshOn:null
- prefillResetOn:null
- prefix:null
- prefixFieldName:null
- readOnly:false
- required:false
- suffix:null
- suffixFieldName:null
- tabIndex:null
- tooltip:null
- type:null
- value:null
Label action
Section titled “Label action”->labelAction() renders a component at the end of the field’s label row — typically a link, such
as a “Forgot password?” link beside a password field:
use Lattice\Ui\Components\Link;
PasswordInput::make('password', 'Password') ->labelAction(Link::make('Forgot password?')->href(route('password.request')));Any component works in the slot, so a badge or a button carrying an action fits the same way.
Fields without a label row — HiddenInput, Checkbox, and fields rendered inside a repeater’s
table layout — drop the label action.
Required
Section titled “Required”->required() marks the field as required, adding the indicator and a required validation rule.
TextInput::make('name', 'Team name') ->required()- autoComplete:null
- autoFocus:false
- columnWidth:"md"
- conditions:null
- copyable:false
- dependsOnAny:false
- dependsOnKeys:null
- disabled:false
- editablePrefill:false
- helperText:null
- label:"Team name"
- labelAction:null
- name:"name"
- placeholder:null
- prefillRefreshOn:null
- prefillResetOn:null
- prefix:null
- prefixFieldName:null
- readOnly:false
- required:true
- suffix:null
- suffixFieldName:null
- tabIndex:null
- tooltip:null
- type:null
- value:null
Disabled
Section titled “Disabled”->disabled() renders the field non-interactive. A disabled field is not submitted with the form.
TextInput::make('name', 'Team name') ->value('Acme Inc') ->disabled()- autoComplete:null
- autoFocus:false
- columnWidth:"md"
- conditions:null
- copyable:false
- dependsOnAny:false
- dependsOnKeys:null
- disabled:true
- editablePrefill:false
- helperText:null
- label:"Team name"
- labelAction:null
- name:"name"
- placeholder:null
- prefillRefreshOn:null
- prefillResetOn:null
- prefix:null
- prefixFieldName:null
- readOnly:false
- required:false
- suffix:null
- suffixFieldName:null
- tabIndex:null
- tooltip:null
- type:null
- value:"Acme Inc"
Read-only
Section titled “Read-only”->readOnly() shows the value but prevents editing. Like a disabled field, a read-only field’s typed
value is not trusted on submit — Lattice drops user input for locked fields and only submits a
server-set ->value() (as in the example below).
TextInput::make('slug', 'Slug') ->value('acme-inc') ->readOnly()- autoComplete:null
- autoFocus:false
- columnWidth:"md"
- conditions:null
- copyable:false
- dependsOnAny:false
- dependsOnKeys:null
- disabled:false
- editablePrefill:false
- helperText:null
- label:"Slug"
- labelAction:null
- name:"slug"
- placeholder:null
- prefillRefreshOn:null
- prefillResetOn:null
- prefix:null
- prefixFieldName:null
- readOnly:true
- required:false
- suffix:null
- suffixFieldName:null
- tabIndex:null
- tooltip:null
- type:null
- value:"acme-inc"
Hidden and visible
Section titled “Hidden and visible”->hidden() drops the field from the rendered form entirely — it is absent from the payload and its
validation is skipped, exactly like every other Lattice component’s shared render gate. ->visible()
is the inverse and reads more naturally when toggling on a condition. Both accept a boolean or a
closure resolved once per request with Lattice’s closure evaluation
utilities.
TextInput::make('internal_note', 'Internal note')->hidden();
TextInput::make('internal_note', 'Internal note')->visible($user->isAdmin());
TextInput::make('internal_note', 'Internal note')->visible(fn ($user) => $user?->isAdmin() ?? false);This is a one-time server decision, not a reactive one — for a field that should show or hide as the
user fills in the rest of the form, use ->visibleWhen()
instead.
When the reason is permission rather than state, reach for ->can() instead of a ->visible()
closure. It takes the same abilities as a definition’s can attribute argument, and ->visible()
cannot widen it:
TextInput::make('salary', 'Salary')->can('payroll.view');See Authorization for how can behaves across pages, definitions, and
components.
To show or hide a field based on another field’s value, see Conditional fields.