Skip to content

Instantly share code, notes, and snippets.

@RodolfoSilva
Last active September 20, 2025 13:43
Show Gist options
  • Select an option

  • Save RodolfoSilva/a3f710deb14005242d8e9182ca3741d6 to your computer and use it in GitHub Desktop.

Select an option

Save RodolfoSilva/a3f710deb14005242d8e9182ca3741d6 to your computer and use it in GitHub Desktop.
LiveView DateTime Picker

Usage

Install Flatpickr with:

npm install --prefix assets flatpickr

Import the Flatpickr CSS in your app.css file:

@import "flatpickr/dist/flatpickr.css";

Then copy the component to your app’s components entry point. After that, you can use it like this:

<.datetime_picker field={@form[:scheduled_to]} label="Data e horário" />
attr :field, Phoenix.HTML.FormField,
doc: "a form field struct retrieved from the form, for example: @form[:email]"
attr :label, :string, default: nil
attr :class, :string, default: nil
def datetime_picker(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []
assigns =
assigns
|> assign(:errors, Enum.map(errors, &translate_error(&1)))
~H"""
<div class={["fieldset mb-2", not Enum.empty?(@errors) && "with-error"]}>
<label :if={@label} for={@field.id} class="label mb-1">{@label}</label>
<div id={"#{@field.id}-picker"} class="relative" phx-hook=".Flatpickr" phx-update="ignore">
<input
type="text"
name={@field.name}
id={@field.id}
placeholder="dd/mm/yyyy hh:mm"
value={normalize_iso_datetime(@field.value)}
class={[@class || "input w-full", @errors != [] && "input-error"]}
/>
</div>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
<script :type={Phoenix.LiveView.ColocatedHook} name=".Flatpickr">
import flatpickr from "flatpickr";
/**
* @type {import("phoenix_live_view").ViewHook & { picker: flatpickr.Instance}}
*/
export default {
mounted() {
const input = this.el.querySelector("input")
this.picker = flatpickr(input, {
enableTime: true,
altFormat: "d/m/Y H:i",
dateFormat: "Z",
minuteIncrement: 1,
time_24hr: true,
altInput: true,
static: true,
})
input.setAttribute("type", "text");
input.setAttribute("style", "display: none;");
},
destroyed() {
this.picker.destroy()
this.picker = null
},
}
</script>
"""
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment