views:

104

answers:

3

what's the easiest way in jquery to take the entire html for a (including the tr itself, not tr innerhtml) and swap it with another one? i'm kinda messing around with replaceWith, but that's swapping the innerHtml and i want to swap the whole TR html. seems like it should be an easy task for jquery. i'm thinking there's gotta be a way to reference the TRs by index and as easy as:

temp = table.children[4];
table.children[4] = table.children[7]
table.children[7] = temp;

of course that's psuedocode, but i'm looking for something as easy as that in jquery...

A: 

Based on the documentation replaceWith (http://docs.jquery.com/Manipulation/replaceWith#content) should do what you want, maybe the selector you are using is targeting something other than the tr?

$("tr").click(function () {
  $(this).replaceWith("<tr><td>Something New!</td></tr>");
});
John Duff
+1  A: 

This should do it:

var sourceRow = $('tr').eq(7);
var targetRow = $('tr').eq(4);

targetRow.after(sourceRow.clone());
sourceRow.replaceWith(targetRow);

In plain english, it inserts the copy of the first row after the second row, then it replaces the original first row with the second.

The reason why I insert a clone of the first row and not the first row itself is that this way we don't lose the position of the first row and can position the second row properly.

If I remember correctly, using replaceWith with a jQuery object will take the element out of it's original place and insert to the new place, but if this is not the case, you then have to remove the targetRow also. Otherwise, this should work.

Tatu Ulmanen
thanks, works great!
mdz
+4  A: 

Nicest would be to wrap it in a reuseable custom function:

$.fn.swap = function(other) {
    $(this).replaceWith($(other).after($(this).clone(true)));
};

So that you can use it as:

one.swap(other);

The clone(true) is used so that events are also taken into account.

Here's an SSCCE which demonstrates swapping rows with its next row (if any):

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2078626 part I</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
        <script type="text/javascript">
            $.fn.swap = function(other) {
                $(this).replaceWith($(other).after($(this).clone(true)));
            };
            $(document).ready(function() {
                $('tr').css('cursor', 'pointer').click(function() {
                    $(this).swap($(this).next());
                });
            });
        </script>
    </head>
    <body>
        <table>
            <tbody>
                <tr><td>row1col1</td><td>row1col2</td><td>row1col3</td></tr>
                <tr><td>row2col1</td><td>row2col2</td><td>row2col3</td></tr>
                <tr><td>row3col1</td><td>row3col2</td><td>row3col3</td></tr>
                <tr><td>row4col1</td><td>row4col2</td><td>row4col3</td></tr>
                <tr><td>row5col1</td><td>row5col2</td><td>row5col3</td></tr>
            </tbody>
        </table>
    </body>
</html>

Here's an SSCCE which demonstrates how it can be used in your particular case:

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2078626 part II</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
        <script type="text/javascript">
            $.fn.swap = function(other) {
                $(this).replaceWith($(other).after($(this).clone(true)));
            };
            $(document).ready(function() {
                $('button.swap').click(function() {
                    $('#table tr:eq(1)').swap($('#table tr:eq(3)'));
                });
            });
        </script>
    </head>
    <body>
        <table id="table">
            <tbody>
                <tr><td>row1col1</td><td>row1col2</td><td>row1col3</td></tr>
                <tr><td>row2col1</td><td>row2col2</td><td>row2col3</td></tr>
                <tr><td>row3col1</td><td>row3col2</td><td>row3col3</td></tr>
                <tr><td>row4col1</td><td>row4col2</td><td>row4col3</td></tr>
                <tr><td>row5col1</td><td>row5col2</td><td>row5col3</td></tr>
            </tbody>
        </table>
        <button class="swap">swap rows 2 and 4</button>
    </body>
</html>

Note that the element index is zero based, hence the 1 and 3 in :eq().

BalusC
that's why i love jquery. there's always a simple, 1 line elegant solution to everything! thanks
mdz