rio517

rio517

Correct strategy for using datepicker attached to an input field with Liveview?

Hi!

I’m prepping to use flatpickr, a date picking library which attaches to a specific input field. I’m curious as to the best approach to integrate this with Liveview.

I’m using alpine.js to reveal the input field and to create the flatpickr instance on my input field. However, when Liveview handles the validation on change, it seems that flatpickr becomes “detached” from the target - the instance is still in memory, but cannot be opened. In the absence of a way to transfer the existing instance to the updated DOM element, I am assuming my best bet is to track and destroy() existing instance(s) and reinitialize via a client hook called on updated.

This might be exactly the right way to do this, but any other suggestions? My JS knowledge has atrophied a bit and I’m new to Liveview, so I’m just looking for validation that I’m not overlooking something.

Thanks so much for reading!

Marked As Solved

RodolfoSilva

RodolfoSilva

This is how I’m using today:

Put this inside the core_components.ex

  attr :id, :string, required: true
  attr :field, Phoenix.HTML.FormField,
    doc: "a form field struct retrieved from the form, for example: @form[:occurred_at]"
  attr :label, :string, default: nil
  def datetime_picker(assigns) do
    ~H"""
    <div id={@id} phx-update="ignore">
      <.input field={@field} phx-hook="DateTimePicker" type="text" label={@label} />
    </div>
    """
  end

Create a new Hook:

import flatpickr from "flatpickr"

/**
 * @type {import("phoenix_live_view").ViewHook}
 */
export const DateTimePicker = {
  mounted() {
    flatpickr(this.el, {
      enableTime: true,
      altFormat: "d/m/Y H:i",
      dateFormat: "Z",
      minuteIncrement: 1,
      time_24hr: true,
      altInput: true,
      static: true,
      wrap: false, 
    })
  },
} 

If you are usign TailwindCSS, put this inside you app.css

/**
 * Flatpickr fix full width
 */
.flatpickr-wrapper {
  @apply relative w-full;
}

And use like that

<.datetime_picker
  id="occurred-at"
  field={@form[:occurred_at]}
  label="Occurred at"
/>

This will work fine with :utc_datetime.

Also Liked

gdub01

gdub01

I’m currently doing it in an input_helper based off of https://dashbit.co/blog/dynamic-forms-with-phoenix:

  defp input(:datetime_select, form, field, opts) do
    date = if Map.has_key?(form.data, field) && !is_nil(Map.get(form.data, field)), do: NaiveDateTime.to_iso8601(Map.get(form.data, field)), else: ""
    content_tag :div, class: "control", phx_update: "ignore" do
      apply(Phoenix.HTML.Form, :text_input, [form, field, [class: "input #{state_class(form, field)}", phx_hook: "datetimeHook", value: date] ++ opts])
    end
  end
import flatpickr from "flatpickr";

export const datetimeHook = { 
  mounted() {
    flatpickr(this.el, {
      altInput: true,
      altFormat: "Y-m-d h:i K",
      dateFormat: "Z",
      enableTime: true,
      parseDate(dateString, format) {
        var wrongDate = new Date(dateString);
        var localizedDate = new Date(wrongDate.getTime() - wrongDate.getTimezoneOffset() * 60000);
        return localizedDate;
      },
    });
  }
}

Saving it as :utc_datetime.

I call it like:
<%= input f, :published_at, field_modifier: "", label: "Publish Date" %>

Though I forget why I have field_modifier: “”

sergio

sergio

My man do you know how much heartburn I suffered today trying to fix this god forsaken thing and your solution pulled me from the depths of hades out of the clutches of Mephistopheles himself?

rio517

rio517

That would probably apply to any datepicking library.

I re-read the docs and missed the fact that one could attach phx-update="ignore" to disable patching on specific DOM nodes. I added this to my input field’s parent and wallah! This obviates the need to manage specific instances.

Of course, if anyone has any better ideas, let me know!


That said, I’m surprised that Liveview patches the entire form when validating. I would have thought Liveview would focus on what was changed, not the entire form. I’m guessing that since Liveview patches elements based on changed assigns, that the round trip of the form_data is the change that causes the DOM patch.. ?? I’m hoping I can find some time to look into that more and maybe open a github issue to gather more info.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29703 241
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement