sort table based on select options using jquery

I’m trying to implement sorting of the table using select options(names/type/doc/date) and click on the button the table should display the sorting result. spent almost a day on this didn’t get any idea where am I going wrong. Do I need to call the same function for each of the below options? Please help. Any help would be appreciated. Thanks in advance. Below is , my code.

$(document).ready(function () { 
    $(document).on("click", "#nameselect select abc ", function() {
  sortTable("nameselect", this);
});


function sortTable(column, me) {
  var table = $(me).parents('table').eq(0),
    rows = table.find('tr:gt(0)').toArray().sort(doComparer($(this).index()))
  me.asc = !me.asc
  if (!me.asc) {
    rows = rows.reverse()
  }

  for (var i = 0; i < rows.length; i++) {
    table.append(rows[i])
  }
}

function doComparer(index) {
  return function(a, b) {
    a = getCellValue(a, index);
    b = getCellValue(b, index);
    return $.isNumeric(a) && $.isNumeric(b) ? a - b : a.toString().localeCompare(b)
  }
}

function getCellValue(row, index) {
  return $(row).children('td').eq(index).text()
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
<div style="margin-left:10px;display:inline-flex;" id="nameselect">
    <select style="width:120px;" required="">
      <option value="">select</option>
      <option class="abc" value="Mary">Names</option>
      <option value="">Type</option>
      <option value="">Doc</option>
      <option value="">Date</option>
    </select>
  </div>  
  <button type=button>Ascending</button>

  <table class="" cellpadding="1" cellspacing="1" style="margin-top:10px;" id="myTable">
    <thead>
      <tr id="table-header">
        <th><label> NAME</label></th>
        <th><label> TYPE</label></th>
        <th><label>Doc</label></th>
        <th ><label>Date</label></th>
      </tr>
    </thead>
    <tbody id="">
      <tr >
        <td ><label class="nameselect">Mary</label></td>
        <td><label>text1</label></td>
        <td><label>word</label></td>
        <td><label style="margin-left:10px">1/1/21</label></td>
      </tr>
      <tr class="" data-type="John">
        <td ><label class="nameselect">John</label></td>
        <td><label>text2</label></td>
        <td><label>Excel</label></td>
        <td><label style="margin-left:10px">31/1/21</label></td>
      </tr>
      <tr class="" data-type="Martin">
        <td><label class="nameselect">Martin</label></td>
        <td><label>text3</label></td>
        <td><label>pdf</label></td>
        <td><label style="margin-left:10px">21/2/21</label></td>
      </tr>
      <tr class="" data-type="Rozi">
        <td><label class="nameselect">Rozi</label></td>
        <td><label>text4</label></td>
        <td><label>powepoint</label></td>
        <td><label style="margin-left:10px">5/10/20</label></td>
      </tr>
    </tbody>
  </table>

4 thoughts on “sort table based on select options using jquery”

  1. You have a lot of unnecessary code. If you want to sort the table, just figure out which column index you want to sort. You can assigned column indices as values for the select options.

    After you pick a column, determine the sorting direction and any options like special formatting to pre-process the values for sorting. As for date sorting, you will need to parse your dates into Date objects or use a library like moment (as seen below).

    I wrapped the sorting function into a single jQuery plugin called $.fn.sortTable.

    (function($) {
      const
        cellValue = (row, index) => index !== -1 ? $(row).children('td').eq(index).text() : 0,
        compareCells = (index, options) =>
          (rowA, rowB) => {
            const colOpts = options[index] || {};
            let
              a = cellValue(rowA, index),
              b = cellValue(rowB, index);
            if (colOpts.dateFormat) {
              a = moment(a, colOpts.dateFormat).valueOf(),
              b = moment(b, colOpts.dateFormat).valueOf()
            }
            return $.isNumeric(a) && $.isNumeric(b) ? a - b : a.toString().localeCompare(b);
          };
      Object.assign($.fn, {
        scanSelectOptionData: function() {
          return [...this.get(0).options].reduce((acc, option, index) => {
            const colOpts = {};
            if (option.dataset.dateFormat) {
              colOpts.dateFormat = option.dataset.dateFormat;
            }
            return { ...acc, [option.value]: colOpts };
          });
        },
        sortTable: function(columnIndex, opts, reverse) {
          let rows = this.find('tbody tr').toArray().sort(compareCells(columnIndex, opts));
          return this.append(reverse ? rows.reverse() : rows);
        }
      });
    })(jQuery);
    
    $(document).ready(function() {
      const
        $table = $('#myTable'),
        $select = $('#nameselect > select'),
        $radio = $('input[name="sort-direction"]');
    
      const sortTable = () => {
        const
          columnIndex = parseInt($select.val(), 10),
          opts = $select.scanSelectOptionData(),
          reverse = $('input[name="sort-direction"]:checked').val() === 'DESC';
        $table.sortTable(columnIndex, opts, reverse);
      };
    
      $select.on('change', sortTable);
      $radio.on('change', sortTable);
    });
    table, th, td {
      border: thin solid grey;
    }
    
    table {
      border-collapse: collapse;
      margin-top: 1em;
    }
    
    th, td {
      padding: 0.5em;
    }
    
    #nameselect, .sort-direction-radio {
      display: inline-flex;
    }
    
    #nameselect > select {
      min-width: 10em;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
    
    <div id="nameselect">
      <select required>
        <option value="-1">select</option>
        <option value="0">Names</option>
        <option value="1">Type</option>
        <option value="2">Doc</option>
        <option value="3" data-date-format="DD/MM/YYYY">Date</option>
      </select>
    </div>
    
    <div class="sort-direction-radio">
      <input type="radio" name="sort-direction" value="ASC" checked />ASC
      <input type="radio" name="sort-direction" value="DESC" />DESC
    </div>
    
    <table id="myTable">
      <thead>
        <tr id="table-header">
          <th>Name</th>
          <th>Type</th>
          <th>Doc</th>
          <th>Date</th>
        </tr>
      </thead>
      <tbody id="">
        <tr>
          <td>Mary</td>
          <td>text1</td>
          <td>word</td>
          <td>1/1/21</td>
        </tr>
        <tr class="" data-type="John">
          <td>John</td>
          <td>text2</td>
          <td>Excel</td>
          <td>31/1/21</td>
        </tr>
        <tr class="" data-type="Martin">
          <td>Martin</td>
          <td>text3</td>
          <td>pdf</td>
          <td>21/2/21</td>
        </tr>
        <tr class="" data-type="Rozi">
          <td>Rozi</td>
          <td>text4</td>
          <td>powepoint</td>
          <td>5/10/20</td>
        </tr>
      </tbody>
    </table>
    Reply

Leave a Comment