1

I have a table with persons and I want to sort them manually, but without drag and drop. I just want so select a person by clicking on the row, select another person by clicking on them and then the two should switch positions.

I've no problem to select one row, but I'm stuck at how to select the second one. I think switching the rows could be possible with jQuery replaceWith.

$(document).ready(function(){

 var selections = new Array(2);

 $("tr").click(function() {

    var selected = $(this).attr('id');

    //highlight selected row
    $(this).toggleClass("marked");

  })

});

I've created a fiddle here: http://jsfiddle.net/zLz929xy/3

Any help or hints would be great.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
BarneyRoss
  • 13
  • 3

4 Answers4

2

Have a look at my fiddle.

I've modified a bit your fiddle structure.

It's easy to understand that it simply get the row and check for a already existing "marked" element. If the table has one switch the elements of the first row with the elements of the second row... If needed you can also add a var oldRowId = $(row).attr('id') and var newRowId = $(element).attr('id') in order to switch also the row ID.

This is a very simplest way in my opinion

$(document).ready(function(){
    $("tr").click(function() {
        var row = $(this);
        
        var check = false;
        $.each($('#people tbody tr'), function(idx, element) {
            if($(element).hasClass('marked')) {
                // old values from row
                var oldId = $(row).find('.id').html();
                var oldName = $(row).find('.name').html();
                
                // new values 
                var rowId = $(element).find('.id').html();
                var rowName = $(element).find('.name').html();
                
                // Replace element
                $(element).find('.id').html(oldId);
                $(element).find('.name').html(oldName);
                
                $(row).find('.id').html(rowId);
                $(row).find('.name').html(rowName);
            
             // check
                check = true;
            }
        });

        if(!check) {
            $(this).toggleClass("marked");
        } else {
            $.each($('#people tbody tr'), function(idx, element) {
             if($(element).hasClass('marked')) {
                 $(element).toggleClass('marked');
                }
            });
        }
    })
});
html {
 font-family: Verdana;
 font-size: 10pt;
}

td{
border: 1px solid;
}

.marked {
 background: #e5e5e5;
 font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="people">
  <tbody>
    <tr>
        <th class="id">ID</th>
        <th class="name">Name</th>
    </tr>

    <tr id="user_1">
        <td class="id">1</td>
        <td class="name">Bob</td>
    </tr>
    <tr id="user_2">
        <td class="id">2</td>
        <td class="name">Carl</td>
    </tr>
    <tr id="user_3">
        <td class="id">3</td>
        <td class="name">Jane</td>
    </tr>
    <tr id="user_4">
        <td class="id">4</td>
        <td class="name">Steven</td>
    </tr>
    <tr id="user_5">
        <td class="id">5</td>
        <td class="name">Sarah</td>
    </tr>
    <tr id="user_6">
        <td class="id">6</td>
        <td class="name">Marc</td>
    </tr>
  </tbody>
</table>
IlGala
  • 3,331
  • 4
  • 35
  • 49
0

I made some changes, hopefully this illustrates how to do it without bothering with arrays and looping or any of that. We'll only ever have one row marked as "marked", so there's no need to iterate or check classes when removing the "marked" class.

Also, since we're always switching the entirety of the rows, we can just grab all of their html instead of splitting it into separate bits of information to track and operate on.

$(document).ready(function(){
    // we need to be able to know the values of both the clicked rows and whether or
    // not something is selected
    var somethingSelected = false;
    var firstRow;
    var firstRowHTML;
    var secondRow;
    
    // when we click a tr, one of two things should happen - we are selecting the first
    // row, or we are picking the second row and making the switch - and which one we
    // do will depend on whether or not the somethingSelected var is true or false
    $("tr").click(function() {
        if (somethingSelected) {
            secondRow = $(this);
            firstRow.html(secondRow.html());
            secondRow.html(firstRowHTML);
            somethingSelected = false;
            $("tr").removeClass("marked");
        } else {
            somethingSelected = true;
            firstRow = $(this);
            firstRowHTML = firstRow.html();
            $(this).addClass("marked");
        }
    }); 
});
html {
 font-family: Verdana;
 font-size: 10pt;
}

td{
border: 1px solid;
}

.marked {
 background: #e5e5e5;
 font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="people">

    <tr>
        <th id="id">ID</th>
        <th id="name">Name</th>
    </tr>

    <tr id="user_1">
        <td headers="id">1</td>
        <td headers="name">Bob</td>
    </tr>
    <tr id="user_2">
        <td headers="id">2</td>
        <td headers="name">Carl</td>
    </tr>
    <tr id="user_3">
        <td headers="id">3</td>
        <td headers="name">Jane</td>
    </tr>
    <tr id="user_4">
        <td headers="id">4</td>
        <td headers="name">Steven</td>
    </tr>
    <tr id="user_5">
        <td headers="id">5</td>
        <td headers="name">Sarah</td>
    </tr>
    <tr id="user_6">
        <td headers="id">6</td>
        <td headers="name">Marc</td>
    </tr>

</table>
Jonathan Bowman
  • 1,606
  • 1
  • 12
  • 17
0

Using the swap function from https://stackoverflow.com/a/698386/2314737:

var selections = new Array(2);

$("tr").click(function() {

  var selected = $(this).attr('id');

  //highlight selected row
  if ($('.marked').length) {
    $(this).swapWith($('.marked'));
    $('.marked').toggleClass("marked");
  }
  $(this).toggleClass("marked");
})


jQuery.fn.swapWith = function(to) {
  return this.each(function() {
    var copy_to = $(to).clone(true);
    var copy_from = $(this).clone(true);
    $(to).replaceWith(copy_from);
    $(this).replaceWith(copy_to);
  });
};
html {
 font-family: Verdana;
 font-size: 10pt;
}

td{
border: 1px solid;
}

.marked {
 background: #e5e5e5;
 font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="people">

  <tr>
    <th id="id">ID</th>
    <th id="name">Name</th>
  </tr>

  <tr id="user_1">
    <td headers="id">1</td>
    <td headers="name">Bob</td>
  </tr>
  <tr id="user_2">
    <td headers="id">2</td>
    <td headers="name">Carl</td>
  </tr>
  <tr id="user_3">
    <td headers="id">3</td>
    <td headers="name">Jane</td>
  </tr>
  <tr id="user_4">
    <td headers="id">4</td>
    <td headers="name">Steven</td>
  </tr>
  <tr id="user_5">
    <td headers="id">5</td>
    <td headers="name">Sarah</td>
  </tr>
  <tr id="user_6">
    <td headers="id">6</td>
    <td headers="name">Marc</td>
  </tr>

</table>
Community
  • 1
  • 1
user2314737
  • 27,088
  • 20
  • 102
  • 114
0

I would personally add a double click event to the second selection on the basis single clicks are too easy to do accidentally.

You could end up correcting mistakes.

Anyway, if this is something you'd consider, you can use the dblclick event and have something like this;

$("tr").dblclick(function(e) {
    if ($('.marked').length == 1) {
        var marked     = $('.marked').html(),
            marked_id  = $('.marked').attr('id'),
            element    = $(this).html(),
            element_id = $(this).attr('id');
        $('tr[id="'+marked_id'+"]').html(element);
        $('tr[id="'+element_id'+"]').html(marked);
        $('tr').removeClass('marked');
    }
});

You simply check if the $('.marked').length is 1, since the dblclick is attached to the element you want to swap out with, which should leave 1 remaining to swap with.

Then you just store the html() of the TR alone with the IDs of both elements, so you can swap them out.

Live preview :: http://jsfiddle.net/MrMarlow/zLz929xy/7/

MrMarlow
  • 856
  • 4
  • 17