Select Component
A searchable select for forms and filters, rendered as a Basecoat combobox. Filtering is handled by basecoat-css itself — no extra JavaScript needed.
Preview
<%= basecoat_select_tag "fruit",
[["Apple", 1], ["Pear", 2], ["Banana", 3], ["Grape", 4], ["Mango", 5]],
selected: 2,
group_label: "Fruits",
placeholder: "Search fruits..." %>
In forms
Use basecoat_select on the form builder. The selected value is read from the model and submitted through a hidden input named model[attribute].
<%= form_for @user do |f| %>
<%= f.basecoat_select :fruit, [["Apple", 1], ["Pear", 2]] %>
<% end %>
Remote options via Turbo Streams
Pass a url and the search input queries your server instead of filtering locally. The results are streamed into the listbox with Turbo.
<%= f.basecoat_select :fruit, [[]], url: "/fruits/search", turbo_frame: "custom_frame" %>
Your controller responds with a Turbo Stream that updates the frame (fruits/search.turbo_stream.erb):
<%= turbo_stream.update "custom_frame" do %>
<% @fruits.each do |fruit| %>
<%= tag.div fruit.name, role: "option", data: { value: fruit.id } %>
<% end %>
<% end %>
Without the turbo_frame option the frame name falls back to the underscored URL (_fruits_search). Make sure it matches the frame in your stream.
Options
| Option | Description | Default |
|---|---|---|
selected | The initially selected value | first choice |
group_label | Heading above the option group | titleized name |
placeholder | Placeholder for the search input | "Search entries..." |
url | Endpoint for remote search via Turbo Streams | — |
turbo_frame | Frame name when using url | underscored URL |
scrollable | Cap the listbox height and scroll | false |