Searchable Combobox
NewA building-block Cotton component for server-side searchable select inputs. Designed to be used with djhtmx components for server-side state management.
API Reference
Architecture: Cotton components handle UI/UX (styling, keyboard nav, accessibility). HTMX components handle the data layer (choices, state, server communication). This follows the same pattern as c-modal. Unlike c-combobox which is purely client-side, this component is designed to work with djhtmx for server-side filtering.
Component Family
| Component | Description | Key Attributes |
|---|---|---|
c-searchable-combobox
|
Main container with fieldset, label, hint, error handling, and input styling. Handles click-away behavior. |
size, multiple, label, hint, error, required, bordered, hx_tag, clickaway_hx
|
c-searchable-combobox.input
|
Search input with keyboard navigation (arrow-down to dropdown, escape to close). |
placeholder, value, search_hx, dropdown_id
|
c-searchable-combobox.option
|
Dropdown option with full keyboard support (arrow up/down, enter, escape). |
value, select_hx
|
c-searchable-combobox.chip
|
Removable selection chip for multiselect mode. Includes hidden input for form submission. |
value, name, remove_hx
|
c-searchable-combobox.dropdown
|
Positioned dropdown container with listbox role. |
oob_attrs
|
Keyboard Navigation
| Key | In Input | In Dropdown |
|---|---|---|
| ↓ | Focus first dropdown option | Focus next option |
| ↑ | — | Focus previous option (or input if at top) |
| Enter | — |
Select option (via select_hx)
|
| Esc | Close dropdown | Close dropdown |
c-searchable-combobox Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
name
|
Form field name for hidden inputs | string |
"combobox"
|
label
|
Field label shown above the input | string |
""
|
placeholder
|
Placeholder text for the search input | string |
"Search..."
|
size
|
Input size variant | string |
"md"
|
multiple
|
Enables multi-select mode with chip display | boolean |
False
|
required
|
Marks the field as required | boolean |
False
|
bordered
|
Adds a border around the input | boolean |
False
|
hint
|
Helper text shown below the input | string |
""
|
error
|
Error message text shown below the input | string |
""
|
hx_tag
|
HTMX tag type wrapping the component (e.g. hx-component)
|
string |
""
|
clickaway_hx
|
HTMX attributes string triggered on click-away to close/reset server state | string |
""
|
Comparison with c-combobox
| Aspect |
c-combobox
|
c-searchable-combobox
|
|---|---|---|
| State management | Client-side (Alpine.js) | Server-side (djhtmx) |
| Filtering | Client-side JavaScript | Server-side QuerySet |
| Options | Passed as JSON array | Rendered from QuerySet |
| Use case | Small, static option lists | Large datasets, database queries |
| Events |
selection-changed (Alpine)
|
*_hx handlers (HTMX)
|
Accessibility
ARIA combobox pattern: the component implements role="combobox" on the input with aria-expanded, aria-haspopup="listbox", and aria-controls pointing to the dropdown. The dropdown uses role="listbox" and each option uses role="option".
Keyboard support: full keyboard navigation is built into the Cotton components — arrow keys, Enter, and Escape are all handled without requiring JavaScript configuration.
Click-away: the clickaway_hx attribute triggers server-side close behavior when the user clicks outside the component. Ensure the close action updates aria-expanded accordingly.
Examples
Usage with djhtmx
{% comment %} In your HTMX template {% endcomment %}
{% load kaiko_ui %}
{% comment %} HTMX tags must be passed as attribute values, not bare attributes {% endcomment %}
<c-searchable-combobox hx_tag="{% hx-tag %}" clickaway_hx="{% on 'clickaway' 'close' %}" size="{{ size }}" error="{{ error }}" multiple="true" label="{{ label }}">
{% for item in selected_choices %}
<c-searchable-combobox.chip value="{{ item.value }}" name="{{ name }}" remove_hx="{% on 'click' 'remove' value=item.value %}">
{{ item.label }}
</c-searchable-combobox.chip>
{% endfor %}
<c-searchable-combobox.input dropdown_id="{{ id }}-dropdown" search_hx="{% on 'input delay:100ms' 'search' %}" />
</c-searchable-combobox>
Static Preview — Multiselect Mode
A static preview showing the component structure. In production, the dropdown and interactions are handled by djhtmx.
<c-searchable-combobox size="md" multiple="true" label="Select Technologies" bordered>
<c-searchable-combobox.chip value="python" name="tech">Python</c-searchable-combobox.chip>
<c-searchable-combobox.chip value="django" name="tech">Django</c-searchable-combobox.chip>
<c-searchable-combobox.input placeholder="Type to search..." dropdown_id="preview-dropdown" />
</c-searchable-combobox>
Static Preview — Single Select Mode
<c-searchable-combobox size="md" multiple="false" label="Select Country" bordered>
<c-searchable-combobox.input placeholder="Search countries..." value="Germany" dropdown_id="single-preview-dropdown" />
</c-searchable-combobox>
Size Variants
<c-searchable-combobox size="sm" label="Small" bordered>...</c-searchable-combobox>
<c-searchable-combobox size="md" label="Medium" bordered>...</c-searchable-combobox>
<c-searchable-combobox size="lg" label="Large" bordered>...</c-searchable-combobox>
Error State
<c-searchable-combobox label="Required Field" error="Please select at least one option" required bordered>
<c-searchable-combobox.input placeholder="Type to search..." dropdown_id="error-dropdown" />
</c-searchable-combobox>