Select
A select dropdown with label, validation states, large lists, Alpine.js binding for dependent selects, and disabled/readonly modes.
@selectfield.Select(selectfield.Config{
ID: "os",
Name: "os",
Label: "Operating System",
Options: []selectfield.Option{
{Value: "mac", Label: "Mac"},
{Value: "windows", Label: "Windows"},
{Value: "linux", Label: "Linux"},
},
})Error State
State: selectfield.StateError recolors the field and shows HelperText as an error.
@selectfield.Select(selectfield.Config{
ID: "os-error",
Name: "os",
Label: "Operating System",
State: selectfield.StateError,
HelperText: "Error: Please select an operating system",
Options: options,
})Success State
State: selectfield.StateSuccess applies the success styling. Mark an Option Selected for the initial value.
@selectfield.Select(selectfield.Config{
ID: "os-success",
Name: "os",
Label: "Operating System",
State: selectfield.StateSuccess,
Options: []selectfield.Option{
{Value: "mac", Label: "Mac", Selected: true},
{Value: "windows", Label: "Windows"},
},
})Large List
Selects handle long option lists (e.g. a country picker) with native scrolling.
@selectfield.Select(selectfield.Config{
ID: "country",
Name: "country",
Label: "Country",
Autocomplete: "country",
Options: countryOptions(),
})Dependent Selects (Alpine.js)
Bind Alpine.Model to share state; Alpine.BindDisabled keeps the second select disabled until the first has a value.
<div x-data="{ firstValue: '', secondValue: '' }">
@selectfield.Select(selectfield.Config{ID: "modelName", Alpine: &selectfield.AlpineConfig{Model: "firstValue"}, Options: models})
@selectfield.Select(selectfield.Config{ID: "year", Alpine: &selectfield.AlpineConfig{Model: "secondValue", BindDisabled: "!firstValue"}, Options: years})
</div>Disabled
Disabled: true blocks interaction.
@selectfield.Select(selectfield.Config{
ID: "os-disabled",
Name: "os",
Label: "Operating System",
Disabled: true,
Options: options,
})Readonly
Readonly: true keeps the selected value submittable but prevents the user from changing it.
@selectfield.Select(selectfield.Config{
ID: "os-readonly",
Name: "os-readonly",
Label: "Operating System",
Readonly: true,
Options: options,
})Shell Mode
Set Shell: true when Select should provide trigger and dropdown chrome while custom templ children own the value. Use ValueExpr for the trigger text and dispatch select-close after a pick.
<div x-data="{ access: 'Viewer' }">
@selectfield.Select(selectfield.Config{
ID: "access-shell",
Label: "Access level",
Shell: true,
TriggerLabel: "Role",
ValueExpr: "access",
}) {
<button type="button" x-on:click="access = 'Admin'; $dispatch('select-close')">Admin</button>
<button type="button" x-on:click="access = 'Viewer'; $dispatch('select-close')">Viewer</button>
}
</div>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
ID | string | "" | Unique id (seeds the trigger id <id>-trigger and option ids). |
Name | string | "" | Form field name. |
Label | string | "" | Label above the select. |
Placeholder | string | "" | Placeholder option shown when nothing is selected. |
Options | []Option | nil | Options (Value, Label, Selected). |
State | State | StateDefault | Validation state: "" (default), "error", "success". |
HelperText | string | "" | Text below the field, recolored by State. |
Disabled | bool | false | Disable the select. |
Readonly | bool | false | Non-editable but submittable. |
Autocomplete | string | "" | HTML autocomplete attribute. |
Alpine | *AlpineConfig | nil | Client-side Alpine bindings (Model, BindDisabled). |
InputAttrs | templ.Attributes | nil | Arbitrary attributes on the select. |
RootClass | string | "" | Extra classes on the container. |
Shell | bool | false | Render only the trigger/dropdown shell and use child content as the dropdown body. |
TriggerLeading | templ.Component | nil | Optional component rendered before the trigger text, such as a swatch or icon. |
ValueExpr | string | "" | Alpine expression used for shell-mode trigger text and aria-label. |
TriggerLabel | string | "" | Static label shown on the left side of a shell trigger, with ValueExpr rendered muted on the right. |