Choices.js creates multiple instances for each wire:navigate

41 views Asked by At

I am using choices.js on my laravel livewire app. choices.js is implemented with alpine.js.

I am loading this within a modal. Whenever I reload the page via "wire:navigate" there is a weird stack-up of events which I don't understand. I tried many ideas, such as checking if the the instances are array and then destroying them...however the problem is something else I suppose:

Here is my code:

x-data="{
    multiple: true,
    value: [],
    options: [
        { value: 1, label: 'QTS' },
        { value: 2, label: 'MGS' },
        { value: 3, label: 'Stocks' },
        { value: 4, label: 'US' },
        { value: 5, label: 'EUR' },
        { value: 6, label: 'quality' },
        { value: 7, label: 'SKE' },
        { value: 8, label: 'trigger' },
        { value: 9, label: 'this' },
    ],
    choicesInstance: null, // Speichert die Choices.js-Instanz
    initialized: false, // Zustandsparameter, um zu verfolgen, ob Choices.js bereits initialisiert wurde

    initializeChoices() {
        // Überprüfen, ob die Choices-Instanz bereits vorhanden ist
        if (this.choicesInstance !== null) {
            // Zerstören Sie die vorhandene Instanz, um eine neue zu erstellen
            this.choicesInstance.destroy();
        }

        // Erstellen Sie eine neue Choices-Instanz
        this.choicesInstance = new Choices(this.$refs.select, {
            removeItemButton: true,
            removeItems: true,
            paste: false,
            allowHTML: true, // Erlauben Sie HTML im Label
            
        });
        
        let refreshChoices = () => {
            let selection = this.multiple ? this.value : [this.value];
            this.choicesInstance.clearStore();
            this.choicesInstance.setChoices(this.options.map(({ value, label }) => ({
                value,
                label,
                selected: selection.includes(value),
            })));
        };

        refreshChoices();

        this.$refs.select.addEventListener('change', () => {
            this.value = this.choicesInstance.getValue(true);
        });

        this.$watch('value', () => refreshChoices());
        this.$watch('options', () => refreshChoices());

        // Markieren Sie als initialisiert
        this.initialized = true;
        console.log('Initialized');
    },

    init() {
        // Initialisierung beim Laden der Seite
        this.$nextTick(() => this.initializeChoices());

        document.addEventListener('modalOpened', () => {
           // console.log('Über MODAL');
            this.initializeChoices();
        });

        window.addEventListener('livewire:navigating', () => {
    // Überprüfen, ob die Choices-Instanz bereits vorhanden ist
    if (this.choicesInstance != null && Array.isArray(this.choicesInstance)) {
        // Zerstören Sie die vorhandene Instanz, um eine neue zu erstellen
        this.choicesInstance.forEach(instance => {
            if (instance) {
                instance.destroy();
                console.log('Choices instance destroyed');
            } else {
                console.log('Failed to destroy Choices instance');
            }
        });
    } else {
        console.log('No Choices instance found to destroy');
    }
});


    }
}" 

Tis is what I get in the console after reloading the page 3 times via wire:navigate:

No Choices instance found to destroy
VM28097:57 Initialized
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:57 Initialized
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:57 Initialized
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:82 No Choices instance found to destroy
VM28097:57 Initialized

When open the modal with the choices select with the function initializeChoices() , I get this warning and error message combo for each prioe wire:navigate event. Here I got it four times:

Warning: Trying to initialise Choices on element already initialised {element: '[data-choice]'}
Error:Uncaught TypeError: Cannot read properties of undefined (reading 'removeLoadingState')

I don't know what to do anymore. I need to trigger initializeChoices() on the modal open because choices.js breaks when I resort a table on the same view. However I am now getting this weired wire:navigate error which I can't solve.

Hope someone can help me out.

0

There are 0 answers