Tom
Tom

Reputation: 1618

Jquery ordering table rows

I'm using the following code to order table rows and it works pretty much as I need.

var $table=$('#Frm1');
var rows = $table.find('tr.grp').get();
rows.sort(function(a, b) {
    var keyA = $(a).attr('data-site');
    var keyB = $(b).attr('data-site');
    if (keyA > keyB) return 1;
    if (keyA < keyB) return -1;
    return 0;
});
$.each(rows, function(index, row) {
    $table.children('tbody').append(row);
})

However some of the entries don't have a value associated with data-site. The attribute is there, but not set.

These rows get added to the top of the table, I'd like them to be at the bottom of the table before table row with id ID=LastGroup

Can anyone advise how I can do this ?

Thanks

Upvotes: 0

Views: 37

Answers (2)

Dekel
Dekel

Reputation: 62566

This answer is based on @T.J.Crowder's answer.
If you want to check speifically for the tr with id="LastGroup" you should check it before any other checks you do:

if ($(a).attr('id') == 'LastGroup') {
    return 1;
}
if ($(b).attr('id') == 'LastGroup') {
    return -1;
}

$("#sort").on("click", function() {
  var $table = $('#Frm1');
  var rows = $table.find('tr.grp').get();
  rows.sort(function(a, b) {
    var keyA = $(a).attr('data-site');
    var keyB = $(b).attr('data-site');
    if ($(a).attr('id') == 'LastGroup') {
      return 1;
    }
    if ($(b).attr('id') == 'LastGroup') {
      return -1;
    }
    if (!keyA) return 1;
    if (!keyB) return -1;
    if (keyA > keyB) return 1;
    if (keyA < keyB) return -1;
    return 0;
  });
  $.each(rows, function(index, row) {
    $table.children('tbody').append(row);
  });
});
<table id="Frm1">
  <tbody>
    <tr class="grp" data-site="a" id="LastGroup"><td>this should be last</td></tr>
    <tr class="grp" data-site="c"><td>c</td></tr>
    <tr class="grp" data-site="a"><td>a</td></tr>
    <tr class="grp" data-site="b"><td>b</td></tr>
    <tr class="grp" data-site><td>(none)</td></tr>
    <tr class="grp" data-site="q"><td>q</td></tr>
  </tbody>
</table>
<input type="button" id="sort" value="Sort">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074445

If the attribute is there but has no value, the value you'll get from attr will be "". So just allow for that:

if (!keyA) return 1;
if (!keyB) return -1;
if (keyA > keyB) return 1;
if (keyA < keyB) return -1;

Example:

$("#sort").on("click", function() {
  var $table = $('#Frm1');
  var rows = $table.find('tr.grp').get();
  rows.sort(function(a, b) {
    var keyA = $(a).attr('data-site');
    var keyB = $(b).attr('data-site');
    if (!keyA) return 1;
    if (!keyB) return -1;
    if (keyA > keyB) return 1;
    if (keyA < keyB) return -1;
    return 0;
  });
  $.each(rows, function(index, row) {
    $table.children('tbody').append(row);
  });
});
<table id="Frm1">
  <tbody>
    <tr class="grp" data-site="c"><td>c</td></tr>
    <tr class="grp" data-site="a"><td>a</td></tr>
    <tr class="grp" data-site="b"><td>b</td></tr>
    <tr class="grp" data-site><td>(none)</td></tr>
    <tr class="grp" data-site="q"><td>q</td></tr>
  </tbody>
</table>
<input type="button" id="sort" value="Sort">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

Related Questions