Components Combo-box
Petal Framework

Combo-box

v0.4.0 +
A dynamic, stylish and feature-rich combo-box as a HEEX component.
You need to be a Pro member to use this component.
Or add your own!

Installation

Import the CSS file in your app.css:

@import "tailwindcss/base";
@import "../../deps/petal_components/assets/default.css";
@import "../../deps/petal_framework/assets/css/combo-box.css"; /* <-- Add this line */
@import "tailwindcss/components";
@import "tailwindcss/utilities";

Properties

          attr :field, :any, doc: "the field to generate the input for. eg. `@form[:name]`. Needs to be a %Phoenix. HTML.FormField{}."

attr :class, :string, default: nil, doc: "the class to add to the input"
attr :wrapper_class, :string, default: nil, doc: "the wrapper div classes"

attr :options, :list,
  doc:
    ~s|A list of options. eg. ["Admin", "User"] (label and value will be the same) or if you want the value to be different from the label: ["Admin": "admin", "User": "user"]. We use https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html#options_for_select/2 underneath.|,
  default: []

attr :multiple, :boolean, default: false, doc: "can multiple choices be selected?"
attr :create, :boolean, default: false, doc: "create new options on the fly?"
attr :help_text, :string, default: nil, doc: "context/help for your field"
attr :max_items, :integer, default: nil, doc: "The maximum number of items that can be selected"

attr :remote_options_event_name, :string,
  default: nil,
  doc:
    "The event name to trigger when searching for remote options. That event must return a li"

attr :remove_button_title, :string,
  default: "Remove this item",
  doc: "The title for the remove item button"

attr :placeholder, :string, default: "Select an option...", doc: "The placeholder text"

attr :tom_select_plugins, :map,
  default: %{},
  doc: ~s|Which plugins should be activated? Pass a map that will be converted to a Javascript object via JSON. eg. `%{remove_button: %{title: "Remove!"}}`. See https://tom-select.js.org/plugins for available plugins.|

attr :tom_select_options, :map,
  default: %{},
  doc: "Options to pass to Tom Select. Uses camel case. eg `%{maxOptions: 1000}`. See https://tom-select.js.org/docs for options."

attr :id, :any,
  default: nil,
  doc: "the id of the input. If not passed, it will be generated automatically from the field"

attr :name, :any,
  doc: "the name of the input. If not passed, it will be generated automatically from the field"

attr :label, :string,
  doc:
    "the label for the input. If not passed, it will be generated automatically from the field"

attr :value, :any,
  doc:
    "the value of the input. If not passed, it will be generated automatically from the field"

attr :errors, :list,
  default: [],
  doc:
    "a list of errors to display. If not passed, it will be generated automatically from the field. Format is a list of strings."

attr :rest, :global,
  include:
    ~w(autocomplete disabled form max maxlength min minlength list
  pattern placeholder readonly required size step value name multiple selected default year month day hour minute second builder options layout cols rows wrap checked accept),
  doc: "All other props go on the input"

        

Single select

Just like a normal select, but a user can search for the option.

          <.combo_box
  label="Pick your favourite fruit"
  options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
  field={@form[:fruit]}
/>

        

Multiple select

The input can take multiple options. You can use backspace/delete to delete options.

          <.combo_box
  multiple
  label="Pick your favourite fruit"
  options={["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]}
  field={@form[:fruit]}
/>

        

If you want to use your live view as a remote data source, you can set the remote_options_event_name option, which is similar to a phx-change event. When a user starts typing this will trigger an event with the name you pass. You handle the event in your live veiw return a list of options. The event will be passed the search term as first argument.

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]}
/>

        

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.