Mike Pala
Mike Pala

Reputation: 806

Sorting a table by number not alphabetically

found this simple solution here on w3

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sort_table_desc

it works great but sorts the table by A to Z even if you put numbers in the table. So if you have values like: 1, 2, 3, 11 ... it will sort it 1, 11, 2, 3. I actualy hope this is a duplicate question but I was not able to find the answer here. How can I get the sorting function to sort no number value? ... and maybe you also know to to get it to sort by date?

Upvotes: 0

Views: 227

Answers (2)

Tomas Varga
Tomas Varga

Reputation: 1440

If you insist on using the linked example, see this part:

  if (dir == "asc") {
    if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
      shouldSwitch= true;
      break;
    }
  } else if (dir == "desc") {
    if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
      shouldSwitch= true;
      break;
    }
  }

It's working with innerHTML, which is always a string, so the comparison operators performs comparison of strings (where "11" < "2"). To make it compare numeric content as actual numbers, you must first convert it to numbers (if the content is not a number, parseFloat results in a NaN object, which is checked for by the isNaN() function):

  var xNumeric = parseFloat(x.innerHTML);
  var yNumeric = parseFloat(y.innerHTML);

  if (dir == "asc") {
    if (!isNaN(xNumeric) && !isNaN(yNumeric) && xNumeric > yNumeric
        || (isNaN(xNumeric) || isNaN(yNumeric)) && x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
      shouldSwitch= true;
      break;
    }
  } else if (dir == "desc") {
    if (!isNaN(xNumeric) && !isNaN(yNumeric) && xNumeric < yNumeric
        || (isNaN(xNumeric) || isNaN(yNumeric)) && x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
      shouldSwitch= true;
      break;
    }
  }

Which translates as "if the compared contents are numeric, compare their numeric values OR if one of them is not, compare them as strings".

Approach to compare dates would be the same - you'd first converted the content to a date object (roughly var xDate = new Date(x.innerHTML);, which is not exhaustive though) and compared the date objects; checking if a variable is a valid date object is a bit harder hough, check this or that SO questions.

Upvotes: 0

Harman
Harman

Reputation: 298

I have taken the part where the asc or dsc comparison is done in the example you shared.

If you look at the sortTable() function in the <script> of the example - you are comparing values as strings, hence the numbers are sorted like - 1, 11, 2, 23, 3

    if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
     //the x.innerHTML returns string
      shouldSwitch= true;
      break;
    }

You have to do something like this:

   if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) {
      //if so, mark as a switch and break the loop:
      shouldSwitch= true;
      break;
    }

Now you'll be comparing numbers, I suggest create a separate function sortNumbers for the number columns or keep the same function sortTable(0, type) -> type params can take in text or number and sort accordingly.

Let me know if you need more explanation. Hope this helps.

Upvotes: 1

Related Questions