Dynamically (ajax) replacing items
Closed this issue · 3 comments
Hi there and thank you for providing Shuffle-js, it is nice.
My problem is similar to the following issue for which you have already supplied a long answer and a working demo:
#171
I simply need to replace existing shuffle children with new ones coming via ajax. However, as far as I can see the case for replacing existing items is not covered. And so I improvised thusly:
// ... I receive via ajax some HTML in response
var jsonobj = JSON.parse(response);
// I create a new dom which is: create a div, innerHTML=mytml
// get the firstChild() of div
var newdom = html2dom(jsonobj.d);
// obj is my original element I wish to replace
window.shufflerObj.shuffle.remove([obj]);
this.shufflerObj.element.replaceChild(newdom, obj);
// obj.parentNode.replaceChild(newdom, obj); // not working
window.shufflerObj.shuffle.add([newdom]);
The old child is removed but the new child is not showing the new child IS SHOWING (sorry) and I get the following error in the console:
TypeError: e.element.classList is undefinedshuffle-item.js:49:6
The error is this:
TypeError: t.parentNode is null shuffle.js:950:8
Also, I get the same error with this:
window.shufflerObj.shuffle.remove([obj]);
obj.parentNode.replaceChild(newdom, obj); // <<<<
//this.shufflerObj.element.replaceChild(newdom, obj);
// obj.parentNode.replaceChild(newdom, obj); // not working
window.shufflerObj.shuffle.add([newdom]);
I am using the latest version as downloaded from your repo (dist dir) just now.
Can you help me? Many Thanks,
p.s. Edited the above after 1hr after I realised the new situation.
I think the reason this is failing for you is that the remove
method actually removes the elements from the DOM. Your code then tries to replaceChild
on them, but they no longer have a parent (because they're not in the DOM).
What I suggest is not using replaceChild
. If you want the replaced items to be in the exact same spots, you'll need to figure out how to either appendChild
or insertBefore
at the correct index. I would probably store the index of each item you're about to remove before removing them so you can map that back to the new items.
Thank you for clarifying this.
With your help I have settled to the following:
// obj is the element I want removed and newobj is the element
// I want inserted at same place/index
var parentnode = obj.parentNode;
var nextsibling = obj.nextElementSibling;
window.shufflerObj.shuffle.remove([obj]);
// If this is removed, the item IS NOT REMOVED from DOM
// only removed from shuffle and not showing but they are there!
parentnode.removeChild(obj);
parentnode.insertBefore(newdom, nextsibling);
window.shufflerObj.shuffle.add([newdom]);
It works UNLESS I am trying to remove the last item. In this case I get the error as before:
TypeError: element.parentNode is null shuffle.js:950:6
I have put debug messages on shuffle.js and in my code. The error seems to occur only if I enable the last window.shufflerObj.shuffle.add([newdom]);
(which is important ;))
But I don't get it why add()
will cause shuffle.js to remove and ONLY when I am operating on the last item. The offending code is not called if I am operating on any other item?
I will try obviously to debug this as much as my poor knowledge of JS allows me.
If I comment out line 950 of shuffle.js (i.e. don't do the removeChild()
) all works fine for me. No duplicates, no errors. (but I have no idea of any side-effects?).
Just an idea: could shuffle.js not worry about the dom and take care only of what was added to it (i.e. not trying to remove elements from the DOM?)
Thanks for your time and please don't spend too much on this (it's not urgent for me) ...
I have found another minor complication regarding Shuffle-js's add([elements,...])
: it does not like the first node of any of the elements
to be added, to be a comment element. It complains with:
TypeError: _this.element.classList is undefined shuffle-item.js:48:4
For example, adding something like:
<!-- here is another shuffle item -->
<div class="card-body">...</div>
...
caused this problem. Mind you it's just the first node should not be a comment. Later comments do not seem to bother it.
This may be a feature or a bug! If you think is worth being filed as a bug, let me know and I will open an issue.
Many Thanks,
a.