Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird behaviour when swapping innerHTML vs outerHTML #2499

Open
paulik123 opened this issue Apr 21, 2024 · 0 comments
Open

Weird behaviour when swapping innerHTML vs outerHTML #2499

paulik123 opened this issue Apr 21, 2024 · 0 comments

Comments

@paulik123
Copy link

paulik123 commented Apr 21, 2024

Hello, I have this weird case. I use HTMX together with TomSelect.
I init my selects after swapping like so:

    document.body.addEventListener('htmx:afterSettle', async (event) => {
        event.detail.target.querySelectorAll("[is-tomselect]").forEach((elem) => {
            new TomSelect(elem, {...});
        });
    });

The returned html looked like so:

<div id="container">
    {% partial %}
    <div id="div_that_gets_sent_in_response" <---- only this div and it's contents get sent in the response
        hx-get="<some_url>" 
        hx-trigger="refresh from:body" 
        hx-swap="outerHTML" 
        hx-target="this"
    
        <select is-tomselect>...</select>
        ....
    </div>
    {% endpartial %}
</div>

First swap eveything worked well, but if I did the swap a second time I would get this error:
Error: Tom Select already initialized on this element
Which is weird because the select was supposed to be replaced with a new fresh one.

The error is thrown by tomselect with this line of code of the constructor:
if (input.tomselect) { throw new Error('Tom Select already initialized on this element'); }
It checks to see if the elements has already been initialized. But all of this takes place after the dom has settled so all elements should be "fresh".

After a lot of debugging I found out that if I change the returned html to one below everything worked no matter how many swaps I did:

<div id="container">
    {% partial %}
    <div id="div_that_gets_sent_in_response" <---- only this div and it's contents get sent in the response
        hx-get="<some_url>" 
        hx-trigger="refresh from:body" 
        hx-swap="innerHTML"  <--- this changed
        hx-target="#container" <--- this changed

        <select is-select>...</select>
        ....
    </div>
    {% endpartial %}
</div>

Somehow changing the swap method to innerHTML instead outerHTML deletes the old tomselect instances and everything works. But using outerHTML keeps the instances alive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant