flowbite
flowbite copied to clipboard
Input tag value updated by Flowbite datepicker doesn't trigger phx-change="validate"
Describe the bug When I select a date from the datepicker, the selected date shows in the date input box as text, but the "validate" event is not fired. The following is my related code based on Flowbite documentation (https://flowbite.com/docs/getting-started/phoenix/)
Hooks.Datepicker = {
mounted() {
const datepickerEl = this.el;
new Datepicker(datepickerEl, {
autohide: true,
format: 'yyyy-mm-dd',
});
},
updated() {
this.mounted();
}
}
To Reproduce Steps to reproduce the behavior:
- Add the datepicker to a form that defines
phx-change="validate"in a Phoenix project based on the documentation (https://flowbite.com/docs/getting-started/phoenix/) - Click on a date on the datepicker
- Notice the "validate" event is not fired.
Expected behavior Step 3 of the Reproduce step should trigger "validate" event
Screenshots
Desktop (please complete the following information):
- OS: [e.g. iOS] Windows 11
- Browser [e.g. chrome, safari] Chrome, Firefox, Edge
- Version [e.g. 22]
Additional context
@jmnda-dev I see you have contributed a lot to this project for Phoenix Liveview integration. Can you please shed some lights on what my issue might be caused by? Thanks.
EDIT: Commented from wrong account
@jmnda-dev I see you have contributed a lot to this project for Phoenix Liveview integration. Can you please shed some lights on what my issue might be caused by? Thanks.
Hmm 🤔, I will have a look once I settle down
@jmnda-dev Just to share my findings. I tried addEventListener("changeDate"..) like the following, and it does trigger phx-change. However, it seems to cause LV to go into some kind of loop showing gradually more repetition of (phx-F5oyNZEPzdxLLwPl update: - {8: 1, 10: {…}}... ) as I click on the datepicker more.
According to what Chris McCord said here (https://elixirforum.com/t/triggering-liveview-form-change-event-from-javascript/37073/2), this looks like it should work, but I can't quite get it to work.
Any pointers will be appreciated. Thanks.
Hooks.Datepicker = {
mounted() {
const datepickerEl = this.el;
new Datepicker(datepickerEl, {
autohide: true,
format: 'yyyy-mm-dd',
});
this.el.addEventListener("changeDate", e => {
let event = new Event("change", {bubbles: true});
this.el.dispatchEvent(event);
})
Also tried modifying Datepicker.js like this, but it still didn't trigger phx-change.
if (newDates.toString() !== datepicker.dates.toString()) {
datepicker.dates = newDates;
refreshUI(datepicker, render ? 3 : 1);
triggerDatepickerEvent(datepicker, 'input'); /// changed from 'changeDate' to 'input' (and also tried 'change') hoping that phx-change will pick up on it.
@puruzio Hi sorry for taking decades to respond 😁️ have been a bit busy. I haven't managed to get it to work. I am still investigating the issue though. I even tried to modify the Datepicker plugin to initialize on phx:page-loading-stop event emitted by liveview, but that didn't work.I will contitue to share my findings for a working solution.
@puruzio So I tested the code you shared for triggering form change events from Javascript and it's working for me:
Hooks.Datepicker = {
mounted() {
const datepickerEl = this.el;
new Datepicker(datepickerEl, {
format: 'yyyy-mm-dd',
autohide: true
});
this.el.addEventListener("changeDate", e => {
console.log("Changed")
let event = new Event("change", {bubbles: true});
this.el.dispatchEvent(event);
})
},
}
Versions:
{:phoenix, "~> 1.7.10"}{:phoenix_live_view, "~> 0.20.1"}flowbite@^2.0.0flowbite-datepicker@^1.2.4
I let me know if it works for you.
@jmnda-dev Happy Thanksgiving! Thank you for taking time to look into this.
As you can see in this screen capture video, I face a few issues.
- The date picker doesn't auto-hide despite the
autohide: truethat is set. - Browser console shows the update cycle repeated increasingly more times as I click on dates.
- The update doesn't seem to take effect on the UI until the next date selection is made. The video shows how a new log is added at the bottom of the screen only after the next date is clicked.
https://github.com/themesberg/flowbite/assets/1150766/2ff64fb9-fbdf-49b8-8f6e-9a7f30fe218e
@puruzio Everything is working fine on my side. Would you like I share my demo app?
@jmnda-dev Yes. That will be great. Thank you!!
@puruzio I have created a demo repo here: https://github.com/jmnda-dev/liveview-flowbite-datepicker-demo
You will notice that the form on the Post listing page is not put in a modal, you are able to use the datepicker. However on the Post detail page, the edit form is in a modal. If you click on the Date Published input, the datepicker is not showing probably because the z-index of the datepicker is lower than that of the modal and other elements on the page. So on the edit form modal on the detail page, click on the Date Published input. the datepicker won't show, then in your browser inspector search for the element with this this class datepicker datepicker-dropdown dropdown absolute top-0 left-0 z-20 pt-2 active block datepicker-orient-top datepicker-orient-left then adjust its z-index(set it higher) and you will see it will show up and you can select dates and the change events are pushed to the server.
@jmnda-dev Thank you! Much appreciated!
@puruzio Perhaps an improvement to that could be made to flowbite-datepicker is to allow the overriding of Tailwind CSS classes for the datepicker because a page might have different elements with varying z-index values, which might cause the datepicker to not work propery. Not sure about this though, just a thought.
One thing to point out in this thread. The date-picker integration guide is flawed: do not call this.mounted(); inside updated callback, as this will initialize the component multiple times. This could work only if you change mounted to st:
mounted() {
if(this.initialized) return;
this.initialized = true;
const datepickerEl = this.el;
new Datepicker(datepickerEl, {
autohide: true,
format: 'yyyy-mm-dd',
});
},
Hey everyone,
I've got some good news - since v2.4.1 the datepicker is now a core component of the Flowbite JS.
That means that everything related to instances, initialization are now ported via the main Instance Manager.
For frameworks like Phoenix you no longer need to separately install the datepicker file/plugin:
https://flowbite.com/docs/components/datepicker/#javascript-behaviour
https://flowbite.com/docs/getting-started/phoenix/#datepicker-plugin
Cheers, Zoltan
Hey everyone,
I've got some good news - since
v2.4.1the datepicker is now a core component of the Flowbite JS.That means that everything related to instances, initialization are now ported via the main Instance Manager.
Awesome 🎉️
One thing to point out in this thread. The date-picker integration guide is flawed: do not call
this.mounted();insideupdatedcallback, as this will initialize the component multiple times. This could work only if you changemountedto st:mounted() { if(this.initialized) return; this.initialized = true; const datepickerEl = this.el; new Datepicker(datepickerEl, { autohide: true, format: 'yyyy-mm-dd', }); },
Yeah that makes sense