orchidjs/tom-select

[Bug]: TomSelect loses selected value when destroyed and recreated

weaverryan opened this issue · 1 comments

Bug description

Hi there!

Apologies if I've missed something obvious! Video below and simple reproducer here: https://github.com/weaverryan/turbo-morph-tom-select-reproducer/tree/tom-select-bug

tom-select-reinitialize.mp4

I work with Turbo, and the next version 8 will come with morphing. The key is that, sometimes, the HTML added by TomSelect will be removed. And so, we need to "destroy" TomSelect and recreate it to restore the rich widget.

This works, except that if you select a value via TomSelect, then destroy and reinitialize, the selected option is lost.

Expected behavior

The expected behavior is that, when you select the option via TomSelect, that updates the underlying <option> element. Then, when TomSelect is reinitialized, TomSelect sees that and uses it as the new, selected value.

Steps to reproduce

Reproducer: https://github.com/weaverryan/turbo-morph-tom-select-reproducer/tree/tom-select-bug

A) Load page
B) Use TomSelect to select an option (e.g. Ice Cream)
C) Run code to destroy TomSelect then recreate it

Instead of initializing with "Ice Cream" as the selected option, it will revert back to the original option (Pizza).

Here is the simplest setup, from the reproducer:

<script type="module">
    import TomSelect from 'https://cdn.jsdelivr.net/npm/tom-select@2.3.1/+esm';

    let tomSelect;
    const initializeTomSelect = () => {
        const select = document.querySelector('select');

        if (tomSelect) {
            tomSelect.destroy();
        }
        tomSelect = new TomSelect(select);
    };
    initializeTomSelect();

    const a = document.querySelector('a');
    a.addEventListener('click', async (event) => {
        event.preventDefault();
        initializeTomSelect();
    });
</script>

And HTML:

<a href="#">Destroy & Recreate</a>

<select>
    <option value="1">Pizza</option>
    <option value="2">Burger</option>
    <option value="3">Fries</option>
    <option value="4">Ice Cream</option>
    <option value="5">Cake</option>
    <option value="6">Pasta</option>
</select>

Additional context

I am VERY aware (and hoping!) that I might be missing something ridiculously simple - e.g. some method call on TomSelect that will "cascade" the selected onto the selected option before destroying that. If I am missing something, that you in advance for pointing me in the right direction!

Cheers!

smehrl commented

@weaverryan It looks like TomSelect caches the original HTML and restores it upon destroy.