diff --git a/lib/backpex/fields/time.ex b/lib/backpex/fields/time.ex new file mode 100644 index 00000000..148918f7 --- /dev/null +++ b/lib/backpex/fields/time.ex @@ -0,0 +1,124 @@ +# credo:disable-for-this-file Credo.Check.Design.DuplicatedCode +defmodule Backpex.Fields.Time do + @default_format "%I:%M %p" + + # credo:disable-for-next-line Credo.Check.Readability.StrictModuleLayout + @moduledoc """ + A field for handling a time value. + + ## Options + + * `:format` - Format string which will be used to format the time value or function that formats the time. + Defaults to `#{@default_format}`. + * `:debounce` - Optional integer timeout value (in milliseconds), "blur" or function that receives the assigns. + * `:throttle` - Optional integer timeout value (in milliseconds) or function that receives the assigns. + + ## Example + + @impl Backpex.LiveResource + def fields do + [ + created_at: %{ + module: Backpex.Fields.Time, + label: "Deliver By", + format: "%I:%M %p" + } + ] + end + """ + use BackpexWeb, :field + + @impl Backpex.Field + def render_value(assigns) do + format = Map.get(assigns.field_options, :format, @default_format) + + value = + cond do + is_function(format, 1) -> format.(assigns.value) + assigns.value -> Calendar.strftime(assigns.value, format) + true -> HTML.pretty_value(assigns.value) + end + + assigns = + assigns + |> assign(:value, value) + + ~H""" +

+ <%= @value %> +

+ """ + end + + @impl Backpex.Field + def render_form(assigns) do + ~H""" +
+ + <:label align={Backpex.Field.align_label(@field_options, assigns, :top)}> + + + + +
+ """ + end + + @impl Backpex.Field + def render_form_readonly(assigns) do + ~H""" +
+ + <:label align={Backpex.Field.align_label(@field_options, assigns, :top)}> + + + + +
+ """ + end + + @impl Backpex.Field + def render_index_form(assigns) do + form = to_form(%{"value" => assigns.value}, as: :index_form) + + assigns = + assigns + |> assign(:valid, Map.get(assigns, :valid, true)) + |> assign_new(:form, fn -> form end) + + ~H""" +
+ <.form for={@form} phx-change="update-field" phx-submit="update-field" phx-target={@myself}> + + +
+ """ + end + + @impl Phoenix.LiveComponent + def handle_event("update-field", %{"index_form" => %{"value" => value}}, socket) do + Backpex.Field.handle_index_editable(socket, value, Map.put(%{}, socket.assigns.name, value)) + end +end