Reputation: 187
I have two <div>
elements that have the same structure, but with different id
-s and name
-s. I want to copy the values of one div into the other, preserving the attributes and copying only the value
attributes.
I tried the following way:
$('#current-1').html($('#next-1').html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="current-1">
<div id="current[1]_div1">Some text for current - div1</div>
<div id="current[1]_someelement2">Some text for current - someelement2</div>
</div>
<div id="next-1">
<div id="next[1]_div1">Some text for next</div>
<div id="next[1]_someelement2">Some text for next - someelement2</div>
</div>
It works, but not as I want it to. The source for ouput looks like:
<div id="current-1">
<div id="next[1]_div1">Some text for next</div>
<div id="next[1]_someelement2">Some text for next - someelement2</div>
</div>
<div id="next-1">
<div id="next[1]_div1">Some text for next</div>
<div id="next[1]_someelement2">Some text for next - someelement2</div>
</div>
However, the preferred way is:
<div id="current-1">
<div id="current[1]_div1">Some text for next</div>
<div id="current[1]_someelement2">Some text for next - someelement2</div>
</div>
<div id="next-1">
<div id="next[1]_div1">Some text for next</div>
<div id="next[1]_someelement2">Some text for next - someelement2</div>
</div>
Is it possible to somehow achieve this? The problem is that the current
as well as next
can have 10, 15 or 20 elements, depending on the type. That's why I think that it will be a bit difficult to refer to all childs.
Upvotes: 2
Views: 209
Reputation: 6491
Give a class to the divs that you want to recursive copy so that you can later select them with DOM traversal order, then use element.cloneNode(true)
input:
<div class ="recursive" id="current-1">
<div id="current[1]_div1">Some text for current</div>
</div>
<div class ="recursive" id="next-1">
<div id="next[1]_div1">Some text for next</div>
</div>
Here is a function to copy the divs to a target div:
function rCopy(container){
var toBeCopied = Array.prototype.slice.call(document.getElementsByClassName("recursive"));
return toBeCopied.reduce(function(ac,d,i,a){ac.appendChild(d.cloneNode(true));return ac;},container)
}
container is the div you want to copy the elements to. Beware to not append this container to the same document as duplicate id's will make a problem
Usage:
rCopy(document.getElementById("someContainer"))
FIDDLE:
https://jsfiddle.net/ibowankenobi/LygpLcko/
If you want to copy the text
nodes of a current div with the text nodes of its nextElementSibling
recursively (including the parents children text nodes if any) then use a recursive function and combine with requestAnimationFrame
to prevent blowing the stack. I went from top to bottom (previous sibling gets its contents from the next), you can go any direction and attach a callback when all is finished. Here is an example:
INPUT:
<div class ="recursive" id="current-1">
<div id="current[1]_div1">Some text for current</div>
<div id="current[1]_div2">Some text-2 for current
<div id="current[1]_div3"> Some inner current <br>
<span>inner inner content current</span>
</div>
</div>
</div>
<div class ="recursive" id="next-1">
<div id="next[1]_div1">Some text for next-1</div>
<div id="next[1]_div2">Some text-2 for next-1
<div id="next[1]_div3"> Some inner next-1 <br>
<span>inner inner content next-1</span>
</div>
</div>
</div>
<div class ="recursive" id="next-2">
<div id="next[2]_div1">Some text for next-2</div>
<div id="next[2]_div2">Some text-2 for next-2
<div id="next[2]_div3"> Some inner next-2 <br>
<span>inner inner content next-2</span>
</div>
</div>
</div>
Here the last div with id next-2 with class recursive wont be touched because it does not have a similar sibling. The function:
function rCopy(current,target){
var sNodes = current.childNodes;
var tNodes = target.childNodes;
for (
var i =0,s=sNodes[i],t=tNodes[i];
i<sNodes.length;
++i,s=sNodes[i],t=tNodes[i]
) {
if (s && t && s.nodeType === 3 && t.nodeType === 3) {
s.nodeValue = t.nodeValue;
continue;
} else if (s && t) {
!function(current,target){
window.requestAnimationFrame(
function(){rCopy(current,target)}
)
}(s,t)
}
}
target.nextElementSibling && target.nextElementSibling.className === "recursive" && window.requestAnimationFrame(function(){rCopy(target,target.nextElementSibling)})
}
Usage:
window.requestAnimationFrame(function(){rCopy(document.getElementById("current-1"),document.getElementById("next-1"))})
Once called by requestAnimationFrame, the chain will continue until no next element sibling is found.
FIDDLE:
https://jsfiddle.net/ibowankenobi/LygpLcko/2/
Upvotes: 0
Reputation: 10081
Here is an easy solution that copies the html()
of all the children()
from an element to another, using .each()
and using the index
of each element:
(That's quite short, I don't even know what to comment in the code!)
// Copy each of the childs of next in the childs of current
$('#current-1').children().each(function(index) {
var next = $('#next-1').children()[index];
$(this).html($(next).html());
});
// Output in console to see ids
console.log($('#current-1').html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="current-1">
<div id="current[1]_div1">Some text for current - div1</div>
<label>Label for current</label>
<div id="current[1]_someelement2">Some text for current - someelement2</div>
</div>
<div id="next-1">
<div id="next[1]_div1">Some text for next</div>
<label>Label for next</label>
<div id="next[1]_someelement2">Some text for next - someelement2</div>
</div>
It works perfectly if you always have the same structure in your "current" and "next" elements.
Hope it helps.
Upvotes: 1