1

I'm a jQuery newbie doing some cargo-cult programming in a Trac template. Please forgive the stupid question.

Trac 1.0.1 (and likely other versions) has a preview feature which uses jQuery.replaceWith() to put new elements -- not just new values -- into a ticket header. Unfortunately, I have a Trac plugin which controls the visibility of elements by setting their display and replaceWith() creates new elements and doesn't copy their attributes. Ideally, I'd have a jQuery function that copied contents from one set of elements to another so I could update the existing elements in place. But something that copies attributes to the new elements would be OK, too. Is this possible?

Let's say I have (all it ORIG) is:

<tr id='x'>
   <td display='none'>ABCD</td>
</tr>

and what I get from the server to update that (call it NEW) is:

<tr id='x'>
  <td>QRST</td>
</tr>

After replace with, I end up with my page containing the second snippet. What I want (call it MERGED) is:

<tr id='x'>
  <td display='none'>QRST</td>
</tr>

The code that does this today is:

$("#ticket").replaceWith(items.filter('#ticket'));

Where I've ended up is:

  function copyHeaderData(f, t) {
    if (f.length != t.length) {
      console.log('Shape mismatch');
    }
    else {
      var i;
      for (i = 0; i < t.length; ++i) {
        t[i].innerHTML = f[i].innerHTML;
      }
    }
  }
  // Update ticket box
  copyHeaderData(items.filter("#ticket").find("td"), $("#ticket td"));
Chris Nelson
  • 3,519
  • 7
  • 40
  • 51

2 Answers2

0

I believe you'd want to use jQuery's .clone() method. From the Documentation:

Create a deep copy of the set of matched elements.

You could create a variable of the element you want to clone, like:

var el = jQuery('.some-element').clone();

Then pass that to replaceWith:

jQuery('.some-other-element').replaceWith(el);
bazeblackwood
  • 1,127
  • 6
  • 16
  • I'd have to do that element by element, right? What I really want is `.copyContentsFrom()` (so I can copy the new data into the old structure) or `.copyAttributesFrom()` (which would let me clone the original, replace it, and then copy the attributes into the updated section of the page from the clone. Otherwise it seems I might as well explicitly walk the DOM and copy the contents. – Chris Nelson Aug 15 '14 at 11:57
  • Sorry, I see what you mean now that you've updated your original question. Do you just need to update the inner content? Can you access the `.innerHTML` of the `td` on the clone and set the `.innerHTML` of the previous original item? That would preserve the parent attributes. – bazeblackwood Aug 15 '14 at 17:21
0

Try

var elem = $(selector-a);
var _elem = $(selector-b);
var clone = elem[0].attributes;
_elem[0].attributes = clone.NamedNodeMap;

See, also

convert one element into a like element ala Div -> Span and retain all attributes

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177