-
-
Save mcrumm/88313d9f210ea17a640e673ff0d0232b to your computer and use it in GitHub Desktop.
// 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 |
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?
@micahsoftdotexe I had a similar issue and the updates below resolved it for me:
<div id="date-pickr" phx-update="ignore">
<div id="starts-at-pickr" class="flatpickr" 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>
const Pickr = {
mounted() {
this.pickr = flatpickr(this.el, {
wrap: true,
appendTo: this.el.querySelector("input"),
static: 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,
appendTo: this.el.querySelector("input"),
static: 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();
},
}
@absowoot Thank you for the help. Unfortunately I am still having issues with the css with the arrows being so large and it still being present even when the input has not been clicked. This time it isn't loading at the bottom of the page but in the right spot Could I have imported it wrong or could I have done something else wrong?
@micahsoftdotexe Try adding a relative
class to the div where phx-hook
is located. Also, double-check that the tailwind classes are being applied IE the arrow SVG should have a width of 1rem with the w-4
class.
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 😂