Describe the bug
Easyadmin adds repeatedly the same 'click' event listener on "delete" buttons for collection items and they stack with each push to the list.
For a given list, if you add one element, it will have a delete button with one listener.
If you add a second one, the first element will now have two listeners, the first one will keep just one.
If you add a third one, the first element will have three listeners, the second element will have two, and the third one will have one.
This then causes even more issue afterwards, because when clicking on 'delete' for the first element, it will fire the same delete event 3 times. Furthermore now that it communicates the collection it belongs to, on the first strike, it will put the collection as it should in the event. But then on the second and third strike, since it's already been deleted, it has no parent anymore, therefore the collection becomes null.
To Reproduce
I used EA 4.29.8, but looking at the code, version 5 is also impacted. As stated before, you just need to add more than one element to the list and look at the event listeners on the delete button of any element who isn't the last one added.
(OPTIONAL) Additional context
Here's a screenshot from my firefox
I've already figured out that the bug is caused by this part (https://github.com/EasyCorp/EasyAdminBundle/blob/5.x/assets/js/field-collection.js#L1)
const eaCollectionHandler = (event) => {
document.querySelectorAll('button.field-collection-add-button').forEach((addButton) => {
const collection = addButton.closest('[data-ea-collection-field]');
if (!collection || collection.classList.contains('processed')) {
return;
}
EaCollectionProperty.handleAddButton(addButton, collection);
EaCollectionProperty.updateCollectionItemCssClasses(collection);
});
document.querySelectorAll('button.field-collection-delete-button').forEach((deleteButton) => {
deleteButton.addEventListener('click', () => {
const collection = deleteButton.closest('[data-ea-collection-field]');
const item = deleteButton.closest('.field-collection-item');
item.remove();
document.dispatchEvent(
new CustomEvent('ea.collection.item-removed', { detail: { deletedElement: item, collection } })
);
EaCollectionProperty.updateCollectionItemCssClasses(collection);
});
});
};
eaCollectionHandler is called for each 'item added' event (and also DOMContentLoaded), then it will iterate on each delete button to add a click listener, without checking if it was already added before or not.
Describe the bug
Easyadmin adds repeatedly the same 'click' event listener on "delete" buttons for collection items and they stack with each push to the list.
For a given list, if you add one element, it will have a delete button with one listener.
If you add a second one, the first element will now have two listeners, the first one will keep just one.
If you add a third one, the first element will have three listeners, the second element will have two, and the third one will have one.
This then causes even more issue afterwards, because when clicking on 'delete' for the first element, it will fire the same delete event 3 times. Furthermore now that it communicates the collection it belongs to, on the first strike, it will put the collection as it should in the event. But then on the second and third strike, since it's already been deleted, it has no parent anymore, therefore the collection becomes null.
To Reproduce
I used EA 4.29.8, but looking at the code, version 5 is also impacted. As stated before, you just need to add more than one element to the list and look at the event listeners on the delete button of any element who isn't the last one added.
(OPTIONAL) Additional context
Here's a screenshot from my firefox
I've already figured out that the bug is caused by this part (https://github.com/EasyCorp/EasyAdminBundle/blob/5.x/assets/js/field-collection.js#L1)
eaCollectionHandler is called for each 'item added' event (and also DOMContentLoaded), then it will iterate on each delete button to add a click listener, without checking if it was already added before or not.