defmodule OrionWeb.Components do use Phoenix.Component @doc """ Renders an input with label and error messages. A `%Phoenix.HTML.Form{}` and field name may be passed to the input to build input names and error messages, or all the attributes and errors may be passed explicitly. ## Examples <.input field={@form[:email]} type="email" /> <.input name="my-input" errors={["oh no!"]} /> """ attr :id, :any, default: nil attr :name, :any attr :label, :string, default: nil attr :value, :any attr :type, :string, default: "text", values: ~w(checkbox color date datetime-local email file hidden month number password range radio search select tel text textarea time url week) attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form, for example: @form[:email]" attr :errors, :list, default: [] attr :checked, :boolean, doc: "the checked flag for checkbox inputs" attr :prompt, :string, default: nil, doc: "the prompt for select inputs" attr :options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2" attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs" attr :rest, :global, include: ~w(autocomplete cols disabled form list max maxlength min minlength pattern placeholder readonly required rows size step) slot :inner_block def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do assigns |> assign(field: nil, id: assigns.id || field.id) |> assign(:errors, Enum.map(field.errors, &translate_error(&1))) |> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end) |> assign_new(:value, fn -> field.value end) |> input() end def input(%{type: "checkbox", value: value} = assigns) do assigns = assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", value) end) ~H"""
<%= render_slot(@inner_block) %>
""" end def translate_error({msg, opts}) do # You can make use of gettext to translate error messages by # uncommenting and adjusting the following code: # if count = opts[:count] do # Gettext.dngettext(<%= @web_namespace %>.Gettext, "errors", msg, msg, count, opts) # else # Gettext.dgettext(<%= @web_namespace %>.Gettext, "errors", msg, opts) # end Enum.reduce(opts, msg, fn {key, value}, acc -> String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end) end) end @doc """ Translates the errors for a field from a keyword list of errors. """ def translate_errors(errors, field) when is_list(errors) do for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts}) end end