Combo-box
A dynamic, stylish and feature-rich combo-box as a HEEX component.
Remote options search with a live component
By default the eventcombo_box_search
is handled on the live view. But sometimes you may have your Combo Box in a live component and want that live component to contain the event handler. In this case you can tell the Combo Box to target the current live component using the @myself
assigns:
<.combo_box
remote_options_event_name="live_component_combo_box_search"
remote_options_target={@myself}
label="Country"
placeholder="Search for a country..."
field={@form[:country]}
/>
The key addition is remote_options_target={@myself}
. This value essentially gets passed along to the Javascript function pushEventTo(selectorOrTarget, event, payload, (reply, ref) => ...)
as the selectorOrTarget
param. See docs.
Create new option
The user can create a brand new option if they like.
<.combo_box
create
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Disabled
Disabled works like any other field.
<.combo_box
disabled
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Max items
Set the max number of items that can be selected.
<.combo_box
label="Pick your favourite fruit"
max_items={2}
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Placeholder
Placeholder text similar to a normal text input.
<.combo_box
placeholder="AI will take our jobs :("
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Option groups
<.combo_box
options={[Birds: ["Eagle", "Seagull"], Animals: ["Dog", "Rhino"]]}
label="Pick your favourite fruit"
field={@form[:fruit]}
/>
Plugins
You can toggle plugins and pass options to them.
See https://tom-select.js.org/plugins for available plugins. We have enabled two by default: “Remove button” and “Checkbox options” for multiple selects. You can disable them though:
Disable remove button
<.combo_box
tom_select_plugins={%{remove_button: false}}
multiple
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Drag and drop
Note that this requires jQuery and jQueryUI. We've made it so these libraries will automatically be fetched from a CDN if the `drag_drop` plugin is enabled.
<.combo_box
tom_select_plugins={%{drag_drop: true}}
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Custom Tom Select options
Simple options
We have two ways of providing Tom Select options. You can pass in a map to the attribute tom_select_options
, which works for options of primitive types such as strings or numbers.
<.combo_box
tom_select_options={%{highlight: false}}
label="Pick your favourite fruit"
options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
field={@form[:fruit]}
/>
Complex options
For complex options that require setting a Javascript function as an option, we have made it so you can reference a global Javascript variable that contains those options:
<script phx-update="ignore" id="customTomSelectOptions">
window.customTomSelectOptions = {
render: {
option_create: function(data, escape) {
return '<div class="create">Create new option for <strong>' + escape(data.input) + '</strong>…</div>';
},
no_results:function(data,escape){
return '<div class="no-results">No results found for "'+escape(data.input)+'"</div>';
},
}
}
</script>
<.h3 class="mt-10">Remote fetching</.h3>
<.combo_box
label="Fetch remotely"
id="fetch_remotely"
tom_select_options_global_variable="customTomSelectOptions"
multiple
remote_options_event_name="combo_box_search"
field={@form[:widget_category_names]}
help_text="The options are fetched remotely in your live view"
/>
In the above code you can see we set a global Javascript variable called customTomSelectOptions
and then pass it to our combo box via the attribute tom_select_options_global_variable="customTomSelectOptions"
.
Note that we merge these options with any other options you pass in, so you can combine the tom_select_options
and tom_select_options_global_variable
methods of passing options.
Customization
You can copy the CSS into your own project:
cp deps/petal_framework/assets/css/combo-box.css ./assets/css
Then modify your `app.css` to point to it.
@import "tailwindcss/base";
@import "../../deps/petal_components/assets/default.css";
@import "combo-box.css"; /* <-- Add this line */
@import "tailwindcss/components";
@import "tailwindcss/utilities";
Now you can customize `combo-box.css` to your needs.
Note that we also use styles from Petal Components for the label, help text and errors.