Search code examples
jquerycloneprependreplacewith

jquery - clone td, prepend, and change new td to div


I'm successfully cloning a series of <td>s and placing them within another series of <td>s, but when I try to replaceWith the new <td>s with <divs>, the <td>s are being stripped away, not replaced.

Basically, I'm taking the first set of <td>s here and prepending a clone of each within the second set of <td>s respectively. This would be the HTML/DOM pre-clone:

<tr>
    <td class="weekTitles 1" nowrap="nowrap">Sun Jun 28</td>
    <td class="weekTitles 2" nowrap="nowrap">Mon Jun 29</td>
    <td class="weekTitles 3" nowrap="nowrap">Tue Jun 30</td>
    <td class="weekTitles 4" nowrap="nowrap">Wed Jul 01</td>
    <td class="weekTitles 5" nowrap="nowrap">Thu Jul 02</td>
    <td class="weekTitles 6" nowrap="nowrap">Fri Jul 03</td>
    <td class="weekTitles 7" nowrap="nowrap">Sat Jul 04</td>
</tr>
<tr>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
    <td class="eventText" valign="top"></td>
</tr>

A snippet from the second sets of <td> shows cloning/prepending is working correctly:

<tr>
    <td class="eventText" valign="top">
        <td class="weekTitles 1" nowrap="nowrap" style="background: red none repeat scroll 0% 0%;">Sun Jun 28</td>
    </td>
    <td class="eventText" valign="top">
        <td class="weekTitles 2" nowrap="nowrap" style="background: red none repeat scroll 0% 0%;">Mon Jun 29</td>
    </td>

...etc...

And my javascript is working fine through the .css background color function (used as a test to see if I'm targeting new cloned element correctly), but once I get to the replaceWith, the new cloned inner <td>s are being stripped away as such:

<tr>
    <td class="eventText" valign="top">
        Sun Jun 28
    </td>
    <td class="eventText" valign="top">
        Mon Jun 29
    </td>

...etc...

When the desired result should look like this (but doesn't because my script is broken):

<tr>
    <td class="eventText" valign="top">
        <div class="weekTitles 1" nowrap="nowrap" style="background: red none repeat scroll 0% 0%;">Sun Jun 28</div>
    </td>
    <td class="eventText" valign="top">
        <div class="weekTitles 2" nowrap="nowrap" style="background: red none repeat scroll 0% 0%;">Mon Jun 29</div>
    </td>

...etc...

Here's my script, working through the .css function but failing after that:

$('.page-calendar .bodyClass tr:nth-child(1) > td.weekTitles').each(function() {
         count = count + 1;
         //console.log(count);
         //console.log(this);
         $(this).clone().prependTo( $(this).closest('table').find('tr:nth-child(2) td:nth-child(' + count + ')') );
// below variable is how I am identifying new element
         var newElem = $('.page-calendar .bodyClass tr:nth-child(2) td.eventText:nth-child(' + count + ') td.weekTitles')[0];
         //console.log(newElem);
         $(newElem).css('background','red');
// this is where it breaks below, no replace of TD with DIV
         $(newElem).each(function (){
            $(this).replaceWith( $(this).html()
            .replace(/<td/gi, '<div')
            .replace(/<\/td>/gi, '</div>')
             );
         });
    });

In short, I think it all comes down to my failure to properly grasp how to write the "$(newElem).each..." function to replace the TDs with DIVs. It's removing the TDs entirely instead of replacing them with DIVs.

Any and all pointers much appreciated. Thank you.


Solution

  • You don't need to clone the elements - all you need to do is create a new div element and apply the class and text from the original to it.

    Note that CSS styling should be applied via a stylesheet, not inline, and that the nowrap attribute is outdated. You should instead again use CSS, white-space: nowrap. Try this:

    $('td.weekTitles').each(function(i) {
        $('<div />', {
            className: $(this).attr('class')
        }).text($(this).text()).appendTo('.eventText:eq(' + i + ')');
    });
    
    .eventText div {
        background: red none repeat scroll 0% 0%;
        white-space: nowrap;
    }
    

    Example fiddle