Date picker retention #39

Open
opened 2025-12-28 23:24:31 +01:00 by adam · 2 comments
Owner

Originally created by @voryzen on GitHub (Apr 1, 2025).

I've added some images below, to visualise the issue.

Whenever the date picker is used in the UI, regardless of the situation/page (as far as I can tell), it remains open/retains itself on the UI, even when you click another item (dropdown box, etc) on the UI.

You should note in the first of the images, that I've opened the date picker, then in the second image, I've clicked on a dropdown box (to change the asset that the expendure is being removed from, I think; though this is irrelevant) and the date picker didn't disappear.

An impactful issue on smaller screens.

HTH

Image

Image

Originally created by @voryzen on GitHub (Apr 1, 2025). I've added some images below, to visualise the issue. Whenever the date picker is used in the UI, regardless of the situation/page (as far as I can tell), it remains open/retains itself on the UI, even when you click another item (dropdown box, etc) on the UI. You should note in the first of the images, that I've opened the date picker, then in the second image, I've clicked on a dropdown box (to change the asset that the expendure is being removed from, I think; though this is irrelevant) and the date picker didn't disappear. An impactful issue on smaller screens. HTH ![Image](https://github.com/user-attachments/assets/689f6aac-bf79-40f7-a55c-b94825b0f812) ![Image](https://github.com/user-attachments/assets/83d0caa0-e529-4ac5-8e5b-21983d4c5bdb)
adam added the bughelp wanted labels 2025-12-28 23:24:31 +01:00
Author
Owner

@eitchtee commented on GitHub (Apr 1, 2025):

I've had this happen to me as well, but it's completely random, or at least I can't seem to reproduce it reliably on my setup (but it does happen from time to time).

I believe the problem resides upstream on air-datepicker, the library we use for date-picking, but I will do a more thorough investigation to see if I can identify why this happens.

@eitchtee commented on GitHub (Apr 1, 2025): I've had this happen to me as well, but it's completely random, or at least I can't seem to reproduce it reliably on my setup (but it does happen from time to time). I believe the problem resides upstream on air-datepicker, the library we use for date-picking, but I will do a more thorough investigation to see if I can identify why this happens.
Author
Owner

@samuelthng commented on GitHub (Sep 9, 2025):

https://github.com/t1m0n/air-datepicker/issues/676

Might be related, the symptoms sound similar.


Updated: Managed to reproduce and 'fix' it in my prod instance.

  1. e065ddeff4/src/datepicker.js (L115-L117)
    This doesn't create a container because the overlay exists from another page.
    And so when it doesn't create a container, the overlay callbacks do not work.

Note

$datepickerOverlay always returns a node on the second instance onward.

  1. e065ddeff4/src/datepicker.js (L151-L154)
    Forcing this guy to always remove the existing container and recreating a new overlay fixes it.
 _createMobileOverlay() {
    // This line fixes it, injecting window.testFix on purpose to test it conditionally.
    if (I !== null && typeof I !== 'string' && window.testFix) I.remove();
    I = a({ className: "air-datepicker-overlay" }),
    P.appendChild(I)
}

Will try to investigate in another session if it's something we're doing that is causing the library to lose context across pages and reinitialise, or is it something that absolutely has to be fixed on the datepicker library's level.

To reproduce:

1: Force isOnMobile to always return true

        function ve() {
            console.log('Override isMobile: `true`');
            return true;
            // return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart"in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0
        }

2: Navigate to any two pages, e.g.: Monthly => Yearly => Recurring Transactions
This shnould force the datepicker to initialise at least twice, on the second time, the overlay will no longer be created as it exists.

  1. Now open any transactions or create anything, and click on a datepicker.

  2. Note that the datepicker no longer gets destroyed when clicking on the overlay (which is supposed to have a registered event listener, but broke due to it being created by another instance of the datepicker class).


Possible solutions

Load the date picker once and tie it to the window, or make it some form of singleton.
I'm not sure how that would look like yet since I have not finish reading the code of the application yet, and am new to htmx.

The other guy solved it by removing reference to the node - but I haven't tested that out.

Possible temporary workaround until it's fixed upstream

We probably could manually destroy all of the overlay nodes before we load in the picker, since it seems to only be invoked only when the page is loaded.

So we just destroy the nodes before invoking the date picker (widget? - still figuring out how Django pushes/triggers JS stuff).

@samuelthng commented on GitHub (Sep 9, 2025): https://github.com/t1m0n/air-datepicker/issues/676 Might be related, the symptoms sound similar. --- ## Updated: Managed to reproduce and 'fix' it in my prod instance. 1. https://github.com/kaipiyann/air-datepicker/blob/e065ddeff40239d3df1b5453dd587c4dd506d1fc/src/datepicker.js#L115-L117 This doesn't create a container because the overlay exists from another page. And so when it doesn't create a container, the overlay callbacks do not work. > [!NOTE] > `$datepickerOverlay` always returns a node on the second instance onward. 2. https://github.com/kaipiyann/air-datepicker/blob/e065ddeff40239d3df1b5453dd587c4dd506d1fc/src/datepicker.js#L151-L154 Forcing this guy to always remove the existing container and recreating a new overlay fixes it. ```js _createMobileOverlay() { // This line fixes it, injecting window.testFix on purpose to test it conditionally. if (I !== null && typeof I !== 'string' && window.testFix) I.remove(); I = a({ className: "air-datepicker-overlay" }), P.appendChild(I) } ``` Will try to investigate in another session if it's something we're doing that is causing the library to lose context across pages and reinitialise, or is it something that absolutely has to be fixed on the datepicker library's level. ## To reproduce: 1: Force isOnMobile to always return true ```js function ve() { console.log('Override isMobile: `true`'); return true; // return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart"in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 } ``` 2: Navigate to any two pages, e.g.: Monthly => Yearly => Recurring Transactions This shnould force the datepicker to initialise at least twice, on the second time, the overlay will no longer be created as it exists. 3. Now open any transactions or create anything, and click on a datepicker. 4. Note that the datepicker no longer gets destroyed when clicking on the overlay (which is supposed to have a registered event listener, but broke due to it being created by another instance of the datepicker class). --- ## Possible solutions Load the date picker once and tie it to the window, or make it some form of singleton. I'm not sure how that would look like yet since I have not finish reading the code of the application yet, and am new to htmx. The other guy solved it by removing reference to the node - but I haven't tested that out. ## Possible temporary workaround until it's fixed upstream We probably could manually destroy all of the overlay nodes before we load in the picker, since it seems to only be invoked only when the page is loaded. So we just destroy the nodes before invoking the date picker (widget? - still figuring out how Django pushes/triggers JS stuff).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WYGIWYH#39