Problem
I’ve run in to a problem working on a set of filters for a liveview in my project. I initially set up one filter which was for “Subject” which is just a drop down. It is important for my application that the filters be added as parameters to the URL so the query parameters are checked to set an initial value of the filter. Next I have to add date range filtering using a timestamp. I decided to use flatpickr to give the user an intuitive way to set the date and time.
I’ve gotten flatpickr set up using hooks and I got the whole URL parameter loop set up but now the issue I’m having is that I need a reset button which will both reset the “Subjects” field and will set the “From Date” and “To Date” fields back to their default values. With only the “Subjects” filters I was doing this by triggering a push_patch
to a route that removed the relevant query parameters. Using this technique doesn’t reset the date filters because their value only gets set in the mount
function.
Part of what I think might be complicating this is having to use phx-update="ignore"
to prevent the flatpickr instances from being destroyed when a phx-change
event is handled. I thought that the updated
method of a hook would be the answer but it doesn’t seem to get run when the form is updated(maybe due to “ignore” mentioned above).
It feels like the solution is to run some javascript that resets those fields when I click “Reset” but it needs to reset those fields to a default value which is dynamic basses on the list of records passed in to the component, so I need the javascript to be able to access the components assigns, I’m at a bit of a loss as to how to get that all strung together. Thank you for any help or nudges in the right direction.
Code
Code is from a demo that I set up to explore the problem better, full demo app can be found HERE the code relevant to this example is in: lib/date_input_web/live
and assets/js/hooks.js
If you start up the project the form is at /date
. Some parts are a bit convoluted for the demo but its to replicate roughly the way my actual application needed to be set up due to other implementation details.
Hook
import flatpickr from 'flatpickr';
export default {
DatePicker: {
mounted() {
console.log(this.el.dataset.datetime);
this.fp = flatpickr(this.el, {
defaultDate: this.el.dataset.datetime,
enableTime: true,
altInput: true,
altFormat: 'm-d-Y H:i',
dateFormat: 'Z',
});
},
updated() {
console.log('Updated...');
},
},
};
Markup
<form id="visits-filters" phx-change="filter">
<!-- Add filters etc here -->
<div id="ignore-from-date" phx-update="ignore">
<label for="from-date">From:</label>
<input
id="visit-from-date-input"
type="text"
name="from-date"
phx-hook="DatePicker"
data-datetime={@from_date}
/>
</div>
<div id="ignore-to-date" phx-update="ignore">
<label for="to-date">To:</label>
<input
id="visit-to-date-input"
type="text"
name="to-date"
phx-hook="DatePicker"
data-datetime={@to_date}
/>
</div>
<div>
<label for="subjects">Filter:</label>
<select name="subject" id="subjects">
<%= options_for_select([{"-- Select Subject --", ""} | ["a", "b", "c"]], @subject) %>
</select>
</div>
<div>
<%= link("Reset", to: "#", phx_click: "reset") %>
</div>
</form>