Skip to content

Instantly share code, notes, and snippets.

@mcrumm
Last active July 13, 2024 22:22
Show Gist options
  • Save mcrumm/88313d9f210ea17a640e673ff0d0232b to your computer and use it in GitHub Desktop.
Save mcrumm/88313d9f210ea17a640e673ff0d0232b to your computer and use it in GitHub Desktop.
flatpickr + LiveView example
// assets/js/app.js
// ...
import Pickr from "./pickr"
const hooks = {
Pickr
}
// ...
let liveSocket = new LiveSocket("/live", Socket, { hooks, params: { _csrf_token: csrfToken } })
// assets/js/pickr/index.js
import flatpickr from "flatpickr";
const Pickr = {
mounted() {
this.pickr = flatpickr(this.el, {
wrap: true,
altInput: this.el.dataset.pickrAltFormat ? true : false,
altFormat: this.el.dataset.pickrAltFormat || "d M Y",
dateFormat: this.el.dataset.pickrDateFormat || "Y-m-d"
})
},
updated() {
const altFormat = this.el.dataset.pickrAltFormat
const wasFormat = this.pickr.config.altFormat
if (altFormat !== wasFormat) {
this.pickr.destroy()
this.pickr = flatpickr(this.el, {
wrap: true,
altInput: this.el.dataset.pickrAltFormat ? true : false,
altFormat: this.el.dataset.pickrAltFormat || "d M Y",
dateFormat: this.el.dataset.pickrDateFormat || "Y-m-d"
})
}
},
destroyed() {
this.pickr.destroy()
}
}
export default Pickr
# lib/my_app_web/live/pickr_live.ex
defmodule MyAppWeb.PickrLive do
use MyAppWeb, :live_view
@impl Phoenix.LiveView
def render(assigns) do
~L"""
<h2>flatpickr example</h2>
<form id="pickr-form" action="#" phx-change="validate">
<div id="starts-at-pickr" class="flatpickr" phx-update="ignore" phx-hook="Pickr" data-pickr-alt-format="<%= @format %>">
<label for="starts-at">Starts at</label>
<input type="text" id="starts-at" name="pickr[starts_at]" placeholder="Select Start Date.." data-input />
</div>
<div id="ends-at-pickr" class="flatpickr" phx-update="ignore" phx-hook="Pickr" data-pickr-alt-format="<%= @format %>">
<label for="ends-at">Ends at</label>
<input type="text" id="ends-at" name="pickr[ends_at]" placeholder="Select End Date.." data-input />
</div>
</form>
<%= if @values do %>
<p>Values: <code><%= @values %></code></p>
<% end %>
<hr />
<form id="format" action="#" phx-change="format">
<label>Alt Format</label>
<input type="text" name="format" value="<%= @format %>"/>
</form>
"""
end
@impl Phoenix.LiveView
def handle_event("validate", %{"pickr" => _} = values, socket) do
{:noreply, assign(socket, :values, inspect(values, pretty: true))}
end
def handle_event("format", %{"format" => format}, socket) do
{:noreply, assign(socket, :format, format)}
end
@impl Phoenix.LiveView
def mount(_, _, socket) do
{:ok, socket |> assign(:values, nil) |> assign(:format, "")}
end
end
@mrcampbell
Copy link

This is what I needed! It's funny because I saw your ElixirConf talk on Phoenix the other day, and I should have known my google search would have led to you one way or another 😂

@micahsoftdotexe
Copy link

Greetings, I am new to Phoenix and LiveView. I am trying to implement this but the issues I am having pertain to the css. It appears as though the css renders the datepicker internals at the bottom of the page constantly and does not wait to be clicked on the datepicker input. Am I doing something wrong or do I need to do some more work for modern versions of liveview?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment