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.