I am trying to use sortableJS with react and redux. I am seeing an issue when I move an item from one list to another and try to update my redux store. (add action + delete action )
my understanding is when react deletes the item from the list in the store and updates the DOM, It can't find the DOM element because it has been moved and throws an exception.
I have been struggling a lot with this issue. I tried to use the clone property to so that the actually object doesn't move and react wouldn't throw me an error while trying to delete it. but it seems that sortableJS moves the actual object leaves a copy there instead, so seeing the same issue again.
Also tried the onMove approach suggested in this https://github.com/RubaXa/Sortable/issues/908. but it wasn't much helpful as I can't determine when actually i would want to update my store.
Error:Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node
Tagging @rhoman @loucapo @dkuang1980 @dkuang1980, as you might have figured out a way handle this.
I am a newbie, Kindly give some suggestions to tackle this. Thanks a lot in advance
I found a temporary fix for now, if it helps anyone
onAdd I basically add the node back to original parent and let redux do the rest of the magic.
onAdd: function (/**Event*/evt) {
var itemEl = evt.item; // dragged HTMLElement
let origParent = evt.from;
origParent.appendChild(itemEl);
// update store
},
Sortable — can not be used directly with React / Angular, etc.
Use https://github.com/SortableJS/react-sortablejs or https://github.com/SortableJS/react-mixin-sortablejs
Thanks @irfanlone for your solution for single items. For anyone trying to do this with multiselect, evt.items does not provide the original parent element if you are nesting draggable lists like this: https://jsbin.com/sepiyid/edit?js,output
So I needed to keep track of the original parent from the onSelect and onDeselect events and add those nodes back from that array:
_selectedItems = [];
new Sortable(el, {
// your sortable settings
multiDrag: true,
onSelect: (evt) => {
const parentEl = evt.from;
const selectedEl = evt.item;
selectedItems.push({ parentEl, selectedEl });
},
onDeselect: (evt) => {
const selectedEl = evt.item;
const isFoundIndex = _selectedItems.findIndex((item) => {
return item.selectedEl === selectedEl;
});
if (isFoundIndex !== -1) {
_selectedItems.splice(isFoundIndex, 1);
}
},
onAdd: (evt) => {
if (evt.items.length > 1) {
// For multi-select.
_selectedItems.forEach((item) => {
item.parentEl.appendChild(item.selectedEl);
});
} else {
// For single select.
const itemEl = evt.item;
let origParent = evt.from;
origParent.appendChild(itemEl);
}
},
Most helpful comment
I found a temporary fix for now, if it helps anyone
onAddI basically add the node back to original parent and let redux do the rest of the magic.