Current section
Files
Jump to
Current section
Files
lib/live_select/component.html.heex
<div
id={@id}
class={class(@style, :container, @container_class, @container_extra_class)}
phx-hook="LiveSelect"
phx-target={@myself}
data-phx-target={assigns[:"phx-target"]}
data-update-min-len={@update_min_len}
data-field={@field.id}
data-debounce={@debounce}
>
<%= if @mode == :tags && Enum.any?(@selection) do %>
<div class={
class(@style, :tags_container, @tags_container_class, @tags_container_extra_class)
}>
<%= for {option, idx} <- Enum.with_index(@selection) do %>
<div class={class(@style, :tag, @tag_class, @tag_extra_class)}>
<%= if @tag == [] do %>
<%= option[:tag_label] || option[:label] %>
<% else %>
<%= render_slot(@tag, option) %>
<% end %>
<button
:if={!option[:sticky]}
type="button"
data-idx={idx}
class={
class(@style, :clear_tag_button, @clear_button_class, @clear_button_extra_class)
}
>
<%= if @clear_button == [] do %>
<.x />
<% else %>
<%= render_slot(@clear_button) %>
<% end %>
</button>
</div>
<% end %>
</div>
<% end %>
<div>
<%= text_input(@field.form, @text_input_field,
class:
class(@style, :text_input, @text_input_class, @text_input_extra_class) ++
List.wrap(
if(Enum.any?(@selection),
do: class(@style, :text_input_selected, @text_input_selected_class)
)
),
placeholder: @placeholder,
phx_target: @myself,
phx_change: "change",
disabled: @disabled,
readonly: @mode == :single && Enum.any?(@selection),
autocomplete: "off",
phx_focus: "focus",
phx_click: "click",
phx_blur: "blur",
value: label(@mode, @selection)
) %>
<%= if @mode == :single && @allow_clear && Enum.any?(@selection) do %>
<button
type="button"
phx-click="clear"
phx-target={@myself}
class={class(@style, :clear_button, @clear_button_class, @clear_button_extra_class)}
>
<%= if @clear_button == [] do %>
<.x />
<% else %>
<%= render_slot(@clear_button) %>
<% end %>
</button>
<% end %>
</div>
<%= if @mode == :single do %>
<%= hidden_input(@field.form, @field.field,
disabled: @disabled,
class: "single-mode",
value: value(@selection)
) %>
<% else %>
<!-- TODO: the stuff below could be replaced with a single hidden, readonly multiselect, but updates don't quite work. So we resort to hidden inputs for now -->
<%= if Enum.empty?(@selection) do %>
<input
type="hidden"
name={"#{@field.form.name}[#{@field.field}_empty_selection]"}
id={"#{@field.id}_empty_selection"}
disabled={@disabled}
data-live-select-empty
/>
<% end %>
<%= for {value, idx} <- values(@selection) |> Enum.with_index() do %>
<input
type="hidden"
name={@field.name <> "[]"}
id={@field.id <> "_#{idx}"}
disabled={@disabled}
value={value}
/>
<% end %>
<% end %>
<%= if Enum.any?(@options) && !@hide_dropdown do %>
<ul class={class(@style, :dropdown, @dropdown_class, @dropdown_extra_class)}>
<%= for {option, idx} <- Enum.with_index(@options) do %>
<li class={
if already_selected?(option, @selection) ||
(@max_selectable > 0 && length(@selection) >= @max_selectable),
do: class(@style, :selected_option, @selected_option_class),
else: class(@style, :available_option, @available_option_class)
}>
<div
class={
class(@style, :option, @option_class, @option_extra_class) ++
List.wrap(
if(idx == @active_option,
do: class(@style, :active_option, @active_option_class)
)
)
}
data-idx={unless already_selected?(option, @selection), do: idx}
>
<%= if @option == [] do %>
<%= option.label %>
<% else %>
<%= render_slot(@option, option) %>
<% end %>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>