Packages

Helper module to generate form elements with DaisyUI

Current section

Files

Jump to
daisyui_forms lib daisyui_forms.ex
Raw

lib/daisyui_forms.ex

defmodule DaisyUIForms do
@moduledoc """
Form helpers using DaisyUI classes
"""
use Phoenix.HTML
@doc """
Generate the required html for an input field
"""
@spec input(Phoenix.HTML.Form.t(), atom, Keyword.t()) :: [tuple]
def input(form, field, opts \\ []) do
type = Phoenix.HTML.Form.input_type(form, field)
wrapper_opts = [class: "form-control w-full max-w-xs"]
label_text = Keyword.get(opts, :label, humanize(field))
content_tag :div, wrapper_opts do
label = label(form, field, label_text, class: "label")
error = error_tag(form, field)
input_opts =
case error do
[] -> [class: "input input-bordered input-sm w-full max-w-xs"]
_ -> [class: "input input-bordered input-sm w-full max-w-xs input-error"]
end
input = apply(Phoenix.HTML.Form, type, [form, field, Keyword.merge(input_opts, opts)])
[label, input, error || ""]
end
end
@doc """
Generate the required html for an textarea field
"""
@spec textarea(Phoenix.HTML.Form.t(), atom, Keyword.t()) :: [tuple]
def textarea(form, field, opts \\ []) do
wrapper_opts = [class: "form-control w-full max-w-xs"]
label_text = Keyword.get(opts, :label, humanize(field))
content_tag :div, wrapper_opts do
label = label(form, field, label_text, class: "label")
error = error_tag(form, field)
input_opts =
case error do
[] -> [class: "textarea textarea-bordered textarea-sm"]
_ -> [class: "textarea textarea-bordered textarea-sm input-error"]
end
input = apply(Phoenix.HTML.Form, :textarea, [form, field, Keyword.merge(input_opts, opts)])
[label, input, error || ""]
end
end
@doc """
Create a select using the given choices
"""
@spec select(Phoenix.HTML.Form.t(), atom, [tuple], any, String.t()) :: [tuple]
def select(form, field, choices, selected, prompt \\ nil) do
wrapper_opts = [class: "form-group w-full max-w-xs"]
content_tag :div, wrapper_opts do
label = label(form, field, humanize(field), class: "label")
error = error_tag(form, field)
input_opts =
case error do
[] -> [class: "select select-bordered select-sm w-full max-w-xs"]
_ -> [class: "select select-bordered select-sm w-full max-w-xs input-error"]
end
input_opts =
case prompt do
nil -> input_opts
_ -> Keyword.put(input_opts, :prompt, prompt)
end
select =
Phoenix.HTML.Form.select(
form,
field,
choices,
Keyword.merge([selected: selected], input_opts)
)
[label, select, error || ""]
end
end
@doc """
Generate the required html for an file inpurt
"""
@spec file_input(Phoenix.HTML.Form.t(), atom, String.t(), Keyword.t()) :: [tuple]
def file_input(form, field, value, opts \\ []) do
wrapper_opts = [class: "form-control w-full max-w-xs"]
label_text = Keyword.get(opts, :label, humanize(field))
content_tag :div, wrapper_opts do
label = label(form, field, label_text, class: "label")
error = error_tag(form, field)
input_opts =
case error do
[] -> [class: "file-input file-input-bordered file-input-sm w-full max-w-xs"]
_ -> [class: "file-input file-input-bordered file-input-sm w-full max-w-xs input-error"]
end
input =
apply(Phoenix.HTML.Form, :file_input, [form, field, Keyword.merge(input_opts, opts)])
prev_data =
if is_nil(value) do
""
else
storage = Keyword.get(opts, :storage)
unless Code.ensure_loaded?(storage) do
raise "Defined storage for DaisyUIForms.file_input/4 is invalid"
end
{:ok, url} = storage.get_signed_url(value)
content_tag :a, href: url do
[value]
end
end
[label, input, prev_data, error || ""]
end
end
@spec error_tag(Phoenix.HTML.Form.t(), atom) :: [tuple]
defp error_tag(form, field) do
Enum.map(Keyword.get_values(form.errors, field), fn error ->
content_tag(:span, translate_error(error),
class: "invalid-feedback",
phx_feedback_for: input_name(form, field)
)
end)
end
def translate_error({_msg, _opts}) do
# TODO: imeplement a behaviour to use translation using gettext
end
end