0

I have a piece of code I use to sort columns in an HTML table and it works perfectly....except for date fields. Alphabet and pure numeric it works great! but when used on a date column the sorter does not work as I want it to. Currently dates get sorted like so:

01-02-2016

02-01-2016

12-12-2014

12-14-2015

What I want to have happen is:

12-12-2014

12-14-2015

01-02-2016

02-01-2016

Here is the JavaScript that I use to make this sort work currently:

var tb, asc1 = 1,
   asc2 = 1,
   asc3 = 1,
   asc4 = 1,
   asc5 = 1,
   asc6 = 1;
                
      function sort_table(tbody, col, asc) {
      var rows = tbody.rows,
                 rlen = rows.length,
                 arr = new Array(),
                 i, j, cells, clen;
      // fill the array with values from the table
         for (i = 0; i < rlen; i++) {
            cells = rows[i].cells;
            clen = cells.length;
            arr[i] = new Array();
            for (j = 0; j < clen; j++) {
            arr[i][j] = cells[j].innerHTML;
            }
          }
       // sort the array by the specified column number (col) and order (asc)
           arr.sort(function (a, b) {
              return (a[col] == b[col]) ? 0 : ((a[col] > b[col]) ? asc : -1 * asc);
           });
       // replace existing rows with new rows created from the sorted array
           for (i = 0; i < rlen; i++) {
              rows[i].innerHTML = "<td>" + arr[i].join("</td><td>") + "</td>";
           }
        }

The onclick function is this:

function test() {
   sort_table(tb, 0, asc1); asc1 *= -1; asc2 = 1; asc3 = 1; asc4 = 1; asc5 = 1; asc6 = 1;
};

How can I make this happen? I am really new to JavaScript and still learning every day. The date format is mm-dd-yyyy as per my example.

Update

I have adopted Daniel Almeida code as he has it working in an example exactly as I want it to but I cannot incorporate it within my own code. When I do the sort seems to be erratic and all over the place. I am now working with the following code:

var sorter = function(id, column, order, isDate) {
  var t = document.getElementById(id);
  var rows = Array.prototype.slice.call(t.rows, 0);

  rows = rows.sort(function(a, b) {

  var dtA = (isDate) ? new Date(a.cells[column].innerHTML) : a.cells[column].innerHTML;
  var dtB = (isDate) ? new Date(b.cells[column].innerHTML) : b.cells[column].innerHTML;

  return (order == 0) ? dtA > dtB : dtA < dtB;

});

for (i = 0; i < rows.length; i++) {
  t.appendChild(rows[i]);
  }

}

I have also created a JS Fiddle but I can't get that to do anything at all. It worries me that I am missing something that I am not aware of.

The reason for splitting the two tables is the bottom table is dynamically loaded and the container div allows for a scroll window instead of a long list of information when there are 100s of returned records.

1
  • Store the actual date objects and sort those, instead of sorting the strings. Only convert the date objects to strings when they need to be displayed. Commented Mar 23, 2016 at 19:17

4 Answers 4

1

First example: sort table

var sorter = function(td, id, column, isDate) {

    var tbl = document.getElementById(id);
    var rows = Array.prototype.slice.call(tbl.rows, 0);

    var order = td.getAttribute("order") == "asc" ? "desc" : "asc";
    td.setAttribute("order", order);

    rows = rows.sort(function(a, b) {

      var valA = a.cells[column].innerText;
      var valB = b.cells[column].innerText;

      var compA = (isDate) ? new Date(valA) : valA;
      var compB = (isDate) ? new Date(valB) : valB;

      if (order == "asc") {
        if (compA < compB) return -1;
        if (compA > compB) return 1;
      }

      if (order == "desc") {
        if (compA > compB) return -1;
        if (compA < compB) return 1;
      }

      return 0;

    });

    for (i = 0; i < rows.length; i++) {
      tbl.appendChild(rows[i]);
    }

  }

EDIT: check this fiddle working with date and text, asc and desc

Sign up to request clarification or add additional context in comments.

7 Comments

This is doing exactly what I want but I can't figure out how to incorporate this into my code above. I want to be able to sort both by the text columns and the date columns. Any idea on how I can combine the two to get the desired effect? I am new so I am guessing I am looking over something really simple...
send the type as parameter.. should work fine.. (id, column, order, type) and check before converting to date.. var dtA = (type == "date") ? new Date(a.cells[column].innerHTML) : a.cells[column].innerHTML;
I added that piece of code but that seemed to go back to sorting the dates as a number instead of a date. Here is the jsfiddle: link. It works on the letter column perfectly but not the date...
I think you forgot to fork.. check this solution
@Craig Howell I've made some changes to work with text and date properly.. check this out
|
1

Use Javascript's built in Date object. An array of dates object can easily be sorted, like so:

var array = [
  new Date("01/02/2016"),
  new Date("02/01/2016"),
  new Date("12/12/2014"),
  new Date("12/14/2015")
];
array.sort();

2 Comments

I think is the cleaner solution!
It may be but the array is comprised of more than just dates. There are text columns and varchar columns as well.
0

You can get time from date object for each item

var arr = [];

arr[i]= new Date(item_date_string).getTime();

You can sort array of integer values, then fill array of equalent dates strings

Comments

0

If you want to use jquery plugin for sorting dates you can refer to this answer also sort date in html table using jquery

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.