30

If I have a table as shown below, and have a up and down arrow that moves rows up and down, how would I go about swapping rows in JQuery?

<tr id="Row1">
  <td>Some label</td>
  <td>Some complex control</td>
</tr>
<tr id="Row2">
  <td>Some label</td>
  <td>Some complex control</td>
</tr>
<tr id="Row3">
  <td>Some label</td>
  <td>Some complex control</td>
</tr>
DotnetDude
  • 11,617
  • 35
  • 100
  • 158

10 Answers10

68

Here's another solution.

To move a row down:

jQuery("#rowid").next().after(jQuery("#rowid"));

To move a row up:

jQuery("#rowid").prev().before(jQuery("#rowid"));
  • 6
    I prefer this to the accepted answer because you don't need to know the id of another row (which may not be where it was when the page was loaded because the rows have been moved around). – paulmorriss Jul 14 '11 at 13:08
  • 6
    Personally I added buttons inside cells to this answer and use `$(this).closest("tr").next().after($(this).closest("tr"));` bound to a `$.click()` function – The Thirsty Ape Feb 26 '14 at 22:06
26
$("#Row1").after($("#Row2"));

will work

cobbal
  • 69,903
  • 20
  • 143
  • 156
  • 4
    This code puts Row2 after Row1. See the documentation for `$.after`. – Vivian River Jul 12 '11 at 22:47
  • 2
    @DanielAllenLangdon is right - `$("#Row1").after($("#Row2"));` will not work. It should be either `$("#Row2").after($("#Row1"));` or `$("#Row1").insertAfter($("#Row2"));` - see: http://api.jquery.com/after/ and http://api.jquery.com/insertAfter/ – rsp Jun 17 '14 at 23:34
9

Here's a slightly expanded example, hoping you will find it useful... :)

$('table').on('click', '.move-up', function () {
    var thisRow = $(this).closest('tr');
    var prevRow = thisRow.prev();
    if (prevRow.length) {
        prevRow.before(thisRow);
    }
});

$('table').on('click', '.move-down', function () {
    var thisRow = $(this).closest('tr');
    var nextRow = thisRow.next();
    if (nextRow.length) {
        nextRow.after(thisRow);
    }
});
Tod Thomson
  • 4,773
  • 2
  • 33
  • 33
6

Here is the code to swap the rows. Lets take #Row1 and #Row3

$('#Row1').replaceWith($('#Row3').after($('#Row1').clone(true)));

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

If you want to move row up and down then use this code. To move row UP

var tableRow = $("#Row1");
tableRow.insertBefore(tableRow.prev());

To move row DOWN

var tableRow = $("#Row1");
tableRow.insertAfter(tableRow.next());
Akshay
  • 354
  • 3
  • 6
4

Here's a plugin that does drag and drop table rows

Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
4

To move Row1 one step down, you'd do:

$me = $("#Row1");
$me.after($me.nextSibling());
Svante Svenson
  • 12,315
  • 4
  • 41
  • 45
  • It's not `.nextSibling()` but `.next()` and it would be either `$me.insertAfter($me.next());` or `$me.next().after($me);` because using `.after()` like you did would insert the element in the same place that it was before. Still your answer led to the most elegant idiom in my opinion, namely to `$me.next().after($me);` - so +1 for that. :) – rsp Jun 17 '14 at 23:29
  • Very smooth syntax. I'm just a bit surprised by the *$me* part. I've always used the syntax of *var me = $("#something");*. What's the advantage of doing it your way? (I've got high hopes for something awesome being presented...) – Konrad Viltersten May 21 '16 at 21:08
1

I am using drag and drop plugin for swap cathegories in table (with subcathegories), and after not working. insertAfter works. similiar topic

Community
  • 1
  • 1
Jaroslav Štreit
  • 415
  • 1
  • 5
  • 16
1

I would try:

var tmp = $ ('#Row1')
$ ('#Row1').remove
$ ('#Row2').after ($ ('#Row1'))

But I guess it’s better to swap rows’ contents instead of swapping rows themselves, so that you can rely on numbering. Thus,

var tmp = $ ('#Row1').html ()
$ ('#Row1').html ($ ('#Row2').html ())
$ ('#Row2').html (tmp)
Ilya Birman
  • 9,834
  • 4
  • 27
  • 31
0

This is a generic function that has 3 parameters: source row, target row and a boolean indicating if the row is moving up or down.

var swapTR = function (sourceTR, targetTR, isBefore) {
    sourceTR.fadeOut(300, function () {
        sourceTR.remove();
        if (isBefore) {
            targetTR.before(sourceTR);
        }
        else {
            targetTR.after(sourceTR);
        }
        sourceTR.fadeIn(300);
        initializeEventsOnTR(sourceTR);
    });
};

You can use it this way:

swapTR(sourceTR, targetTR, true);
Francisco Goldenstein
  • 13,299
  • 7
  • 58
  • 74
0

I usally do something like this:

<table id="mytable">
    <tr>
        <td>-------------ROW 1-----------</td>
        <td><input type="button" value="↑" class="move up" disabled /></td>
        <td><input type="button" value="↓" class="move down" /></td>
    </tr>
    <tr>
        <td>-------------ROW 2-----------</td>
        <td><input type="button" value="↑" class="move up" /></td>
        <td><input type="button" value="↓" class="move down" /></td>
    </tr>
    <tr>
        <td>-------------ROW 3-----------</td>
        <td><input type="button" value="↑" class="move up" /></td>
        <td><input type="button" value="↓" class="move down" /></td>
    </tr>
    <tr>
        <td>-------------ROW 4-----------</td>
        <td><input type="button" value="↑" class="move up" /></td>
        <td><input type="button" value="↓" class="move down" disabled /></td>
    </tr>
</table>
<script>
    $('#mytable input.move').click(function() {
        var row = $(this).closest('tr');
        if ($(this).hasClass('up')){
            row.prev().before(row);
        }

        else{
            row.next().after(row);
        }            

        $(this).closest('table').find('tr:first').find('td:eq(1) input').prop('disabled', true);
        $(this).closest('table').find('tr:last').find('td:eq(2) input').prop('disabled', true );
        $(this).closest('table').find('tr').not(':first').not(':last').find('td:eq(1) input').prop('disabled', false);
        $(this).closest('table').find('tr').not(':first').not(':last').find('td:eq(2) input').prop('disabled', false);
    });
</script>

Editor Example

So this also siables UP in first row and DOWN in last row. You may change it to go on top again if going down in last row. But thats how i've needed it.

Greetings

Taki7o7
  • 197
  • 2
  • 11