Autocomplete

An autocomplete component that allows users to select from a list of options.

<.autocomplete
  name="provider"
  label="Watch Provider"
  options={[
    {"Netflix", "netflix"},
    {"Amazon Prime Video", "amazon"},
    {"HBO Max", "hbo"}
  ]}
/>

Labels

Add sublabels, descriptions, and help text to the autocomplete component.

Select your primary role

Choose your role to customize your experience

Affects available features and reports
<.autocomplete
  name="provider"
  label="Watch Provider"
  options={[
    {"Netflix", "netflix"},
    {"Amazon Prime Video", "amazon"},
    {"HBO Max", "hbo"}
  ]}
/>

Grouped

Group options by category.

<.autocomplete
  name="company"
  label="Production Company"
  options={[
    {"United States",
     [
       {"Walt Disney Pictures", "disney"},
       {"Warner Bros. Pictures", "warner"},
       ...
     ]},
    {"United Kingdom",
     [
       {"Working Title Films", "working_title"},
       {"BBC Films", "bbc"},
       ...
     ]}
  ]}
/>

Filter options via LiveView event.

<.autocomplete
  name="movie"
  label="Movies"
  class="max-w-[400px] max-h-[400px]"
  options={Enum.map(@movies, &{&1.title, &1.id})}
  on_search="search_movies"
/>

<!--
# LiveView implementation example:
def mount(socket) do
  {:ok, movies} = MyApp.Movies.search("batman")
  {:ok, socket |> assign(movies: movies)}
end

def handle_event("search_movies", %{"query" => query}, socket) do
  {:ok, movies} = MyApp.Movies.search(query)
  {:noreply, socket |> assign(movies: movies)}
end
-->

Option customization

Customize the autocomplete options to better fit your needs.

<.autocomplete field={f[:user_id]} options={Enum.map(@users, &{&1.full_name, &1.id})} on_search="search_users">
  <:option :let={{label, value}}>
    <div class="flex items-center gap-3 p-2 rounded-lg [[data-highlighted]_&]:bg-zinc-100 [[data-selected]_&]:bg-blue-100">
      <img src={"https://i.pravatar.cc/150?u=#{value}"} class="size-8 rounded-full" />
      <div>
        <div class="font-medium text-sm">{label}</div>
        <div class="text-xs text-zinc-500">{user_by_id(value, @users).email}</div>
      </div>
    </div>
  </:option>
</.autocomplete>

Empty state

Customize the empty state content to include custom messages and actions.

Search company departments

<.modal id="new-department">
  <!-- form submits to save_department -->
</.modal>

<.form for={@form} phx-submit="save">
  <.autocomplete
    field={@form[:department]}
    label="Department"
    placeholder="Select a department"
    description="Search company departments"
    options={@departments}
  >
    <:empty_state>
      <.button class="w-full" variant="ghost" size="sm" type="button" phx-click={Fluxon.open_dialog("new-department")}>
        <.icon name="hero-plus" class="size-4" /> Create new department
      </.button>
    </:empty_state>
  </.autocomplete>
</.form>

<!--
def handle_event("save_department", %{"name" => name}, socket) do
  departments = [...] # Save and update the list to include the new department.
  form = to_form(...) # Update the form to reflect the newly created department.

  {:noreply,
    socket
    |> assign(departments: departments, form: form)
    |> Fluxon.close_dialog("new-department")}
end
-->