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"},
},
})Built-in text: the development API provides expressions.Select for application defaults, request preferences, and individual component overrides. Read the expression guide.
HTMX Filter
InputAttrs accepts hx-trigger=change. Mouse and keyboard picks emit one bubbling change after the submitted value is current. Initial rendering, same-value picks, and parent Alpine.Model updates are silent. External input/change synchronization emits no extra event. Shell mode leaves value and events to its children.
<form>
@selectfield.Select(selectfield.Config{
ID: "allocation-type", Name: "type", Label: "Allocation type",
Options: []selectfield.Option{
{Value: "", Label: "All types", Selected: true},
{Value: "allocated", Label: "Allocated"},
{Value: "reserved", Label: "Reserved"},
},
InputAttrs: templ.Attributes{
"hx-get": "/api/components/select/filter", "hx-trigger": "change",
"hx-target": "#allocation-result", "hx-include": "closest form",
},
})
<p id="allocation-result" aria-live="polite">Showing all types</p>
</form>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>External Draft Restoration
Restore persisted state by setting the hidden submission input identified by Config.ID, then dispatching a bubbling input or change event. Select synchronizes the visible label and live ARIA selection.
@selectfield.Select(selectfield.Config{
ID: "draft-os",
Name: "draft-os",
Label: "Draft operating system",
Options: options,
})
<button
type="button"
x-on:click="
const input = document.getElementById('draft-os');
input.value = 'linux';
input.dispatchEvent(new Event('change', { bubbles: true }));
"
>Restore Linux draft</button>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>Go API
v0.4.0The examples above cover behavior and composition. pkg.go.dev is the canonical reference for exported types, functions, methods, and Go documentation.
github.com/araihu/goshtoso/components/select