tolik
tolik

Reputation: 187

Copying values of HTML div

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

Answers (2)

ibrahim tanyalcin
ibrahim tanyalcin

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

Takit Isy
Takit Isy

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

Related Questions