bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
35.35k stars 1.18k forks source link

Migrate from v1.9.12 to v2.0.0 breaks some layout and behaviour of a dropdown button #2684

Open maj2c opened 1 week ago

maj2c commented 1 week ago

Hi, After I updated the htmx version from 1.9.12 to 2.0.0 I get layout issue (see screenshots below) but I can not pin point the CSS/class causing this or get overridden after the swap of the element content. Beside the above I noticed that a dropdown button for switching page language does not work (no click event is fired) when the v2.0.0 is used. There is no error in the console. In the project I use Syncfusion components, bootstrap and htmx. Any one has an idea how to trace / pin point the cause or facing similar behaviour?

Layout with version 1.9.12: htmx_v1_9_12

Layout with version 2.0.0: htmx_v2_0_0

Telroshan commented 1 week ago

Hey, I'm afraid we'll need more information to be able to help you! Htmx is a JS library and except the temporary classes it adds during the requests processes, doesn't do anything regarding CSS so that sounds very strange. Is this table in the initial page or does it get swapped in by htmx after a certain action ? If the latter, could you provide the HTML snippets fed to htmx in both cases and the actual output in the DOM? For example, htmx 2 uses template fragments, which was previously an opt-in parameter in htmx 1 (see htmx.config.useTemplateFragments), so I'm thinking it might be a related issue?

maj2c commented 1 week ago

Hi, Thank you for the reply and looking into this issue. The main div gets swapped on every menu click. I compared the response result of the menu click and they are the same. I did a console.log(htmx.config.useTemplateFragments) got undefined. Forced it to false but that did not change the behaviour. Added the but that did not help. Compared the DOM of first visit of a menu against the second click of the menu and I see they are the same except for missing syncfusion grid css classes. Besides that, the row click event does not fire when the grid is loaded for the second time.

At first I thought it is an issue with the grid, now I see any div content swapped with data containing the same syncfusion element such as grid or dashboard, the layout is broken and the component events do not fire.

I tried to get you the requested snippets and actual output in the DOM, but I am not sure I am allowed to post it in here. Will try to explain the flow and behaviour, hope this helps: There is a menu div, all the menu items swap the main div content. The data swapped may contain (A) plain text, (B) dashboard component or (C) grid component. When I navigate from menu A to B or C layout is fine. When navigating from B to C the layout is fine. But, from B to B or C to C the layout and events are broken.

Thank you in advance for looking into this issue.

Telroshan commented 1 week ago

Thanks for the details. So, if I understood correctly, when going from C to C let's say, the HTML is exactly the same, except the CSS classes aren't there anymore?

I'm thinking of 2 ideas that you'd have to check for yourself, just plain guesses here:

Hope this helps, let me know!

maj2c commented 1 week ago

Hi again,

Q: Are those CSS classes in the initial HTML of your request's response? A: No, they get added automatically from Syncfusion component initialisation. I have attached a file with the HTML snippert and the JS functions called from own global/central JS file.

I tried to add the attached HTML snippert manually into the DOM as you suggested, the Syncfusion component (in this case the grid) did not get initialise. No errors in the console.

After reviewing the hx-swap configuration I came across htmx.config.defaultSettleDelay. I have forced it on 5000 and did the test again and I found out within the 5 seconds the layout is correct and the event listeners working too. Once the settleDelay is timed out the grid layout changes and listeners do not work anymore. There is no errors in console. I confirmed that the data is not from cache by changing the values in database before requesting the html snippert.

Thus, maybe something changed between version 1.9.12 and 2.0.0 regarding the settle logic?

HTML_snippert_js_functions.txt

Telroshan commented 1 week ago

Hmmm looking at the code, it seems like a typical settling-messing issue, but if it's that, it would be weird that it was working previously as it's a common problem.

To confirm, could you try to set htmx.config.attributesToSettle to an empty array?

By default, the class attribute is "settled" which is this trick that htmx uses to play transitions properly, that clones attributes on an element before and after the swap. In this case, the issue could be that the saved class attribute value is the one before your lib actually does its processing, thus when the settling occurs, the class is reverted to its initial value, i.e. without the lib's classes that were added in the meantime thus out of htmx's sight.

If the above test works (i.e. using an empty htmx.config.attributesToSettle array to disable settling altogether), then it's indeed a timing issue. In the latter case, you might want to use a htmx:afterSettle event listener, to call your sd_sPrepareAndAddTheMainGrid and sd_sRowSelectedOrDeselected functions, instead of calling them in this inline script which would mess up timings. The goal here would be to wait for htmx to settle the element before initializing your component, ensuring no overlap occurs. Of course, if you don't care about CSS transitions at all here, you might just as well disable setting altogether, that's also an option!

Hope this helps!

maj2c commented 1 week ago

Thank you Telroshan for your clear explanation and support. Setting the htmx.config.attributesToSettle to an empty array resolved the issue. I did not notice any CSS transitions drawback/missing. Thus, will keep it that way for the time being.

I am puzzled too regarding why it is working in v1.9.12 but not v2.0.0, clearly there is a conflict between HTMX and Syncfusion in the way I am using it. I wonder if they use/refer older version of HTMX in their lib and that causing conflict :) Because, the DropDownButton component used for switching page language does not work with v2.0.0 even with empty htmx.config.attributesToSettle. I resolved that by using a different component.

Telroshan commented 1 week ago

Setting the htmx.config.attributesToSettle to an empty array resolved the issue

Good to hear! So that's indeed a normal situation ; since htmx settles attributes, you have 2 options available;

For the record, it should have not been working in htmx 1.9.12 either as it's been a common gotcha for years now, so make sure you don't rely on such unpredictable behavior anywhere else!

does not work with v2.0.0 even with empty htmx.config.attributesToSettle

Sounds weird! Again, I don't know that lib at all, but it might be an issue due to how you wire htmx and that lib together, feel free to share some code if you'd want to investigate!