1

I am working on a web app which I am new at but I have been developing apps for many years for the business forms industry so am not new at development but am pretty new at web dev.

Below is a stripped down sample to show my problem that I am running on Chrome. I picked up a solution from Sort table in HTML by column with date values desc using only javaScript and removed the 'by date' part to make it easier. The problem seems to be in the rows.sort() part as it doesn't seem to be sorting the array at all.

The comments in the code that start with //'by MPG' are my comments and the others from the downloaded code. I do understand that jquery can do this but I want to stay with JavaScript as I really dont want to load and learn another language.

function calcbal() {
  sortByDate();
}

// Also I've introduced a <tbody> into your table so that I can just sort the data rows and completely ignore the header row.
function sortByDate() {
  var tbody = document.querySelector("#cashflow tbody");

  var rows = [].slice.call(tbody.querySelectorAll("tr")); // get trs as array for ease of use
  console.log("rows b4 sort: ");
  console.log(rows); //'by MPG' added for debugging
  rows.sort(); //'by MPG' i think this line is where the problem is. ** * PROBLEM ** *
    console.log("rows after sort: ");
  console.log(rows); //'by MPG' added for debugging
  rows.forEach(function(v) {
    tbody.appendChild(v); // note that .appendChild() *moves* elements
  });
}
table {
  table-layout: fixed;
  empty-cells: show;
  font-family: Verdana, sans-serif;
  font-size: .8em;
  width: 100%;
  <!--874px;
  -->table-layout: fixed;
  overflow: hidden;
  white-space: nowrap;
  text-align: left;
  border: 1px solid black;
  border-collapse: collapse;
  padding: 5px;
}

th {
  padding: 3px;
  font-size: .84em;
}

td {
  padding: 3px;
  font-size: .9em;
}

tr:nth-child(odd) {
  background: #eee;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <button onclick="calcbal()">Sort 1st col</button>
  <table id=cashflow contenteditable>
    <thead>
      <tr>
        <th width="40px" contenteditable="false">Sortcell</th>
        <!--0-->
        <th width="115px" contenteditable="false">AccountName</th>
        <!--1-->
        <th width="40px" contenteditable="false">PayDate</th>
        <!--2-->
        <th width="40px" contenteditable="false">DueDate</th>
        <!--3-->
        <th width="32px" contenteditable="false">Cycle</th>
        <!--4-->
        <th width="34px" contenteditable="false">Method</td>
          <!--5-->
          <th width="41px" contenteditable="false">AutoPay</th>
          <!--6-->
          <th width="150px" contenteditable="false">Comment</th>
          <!--7-->
          <th width="45px" contenteditable="false">PymtDue</th>
          <!--8-->
          <th width="34px" contenteditable="false">Budget</th>
          <!--9-->
          <th width="66px" contenteditable="false">PymtSched</th>
          <!--10-->
          <th width="38px" contenteditable="false">Balance</th>
          <!--11-->
          <th width="200px" contenteditable="false">URL</th>
          <!--12-->
          <th width="39px" contenteditable="false">AcctBal</th>
          <!--13-->
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>200101</td>
        <td>Bank Account xxxx</td>
        <td>01/01/20</td>
        <td>01/01/20</td>
        <td>None</td>
        <td>None</td>
        <td>None</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td>https://www.</td>
        <td>1000</td>
      </tr>
      <tr>
        <td>210401</td>
        <td>APLACE4SPACE</td>
        <td>04/01/21</td>
        <td>04/01/21</td>
        <td>Monthly</td>
        <td>Online</td>
        <td>None</td>
        <td></td>
        <td>79</td>
        <td></td>
        <td>79</td>
        <td></td>
        <td>https://www.aplace4space.com/</td>
        <td>0</td>
      </tr>
      <tr>
        <td>210331</td>
        <td>RENT TO DOUG</td>
        <td>03/31/21</td>
        <td>03/31/21</td>
        <td>None</td>
        <td>None</td>
        <td>None</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td>https://www.</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>
</body>

</html>

2
  • 3
    You'll have to create a sort comparator function so that you can compare a row to another row and tell .sort() what the ordering should be. Commented Mar 26, 2021 at 14:57
  • The default for .sort if you don't pass it a function is UTF-16 code unit values, which is almost certainly not what you want. Also, jQuery isn't a language (not even an embedded DSL like JSX) it's just a library. Commented Mar 26, 2021 at 14:59

1 Answer 1

0

As mentioned by others in the comments you need to supply a function to the compareFunction parameter. Otherwise the sort function compares the string representation of your rows which is the same for all rows: [object HTMLTableRowElement].

In the example below I use firstElementChild to get the first element of the row. It seems like it's filled with an integer value so i converted the textual content to an integer. This integer can than be used to compare 2 rows.

See documentation on sort()

function calcbal() {
  sortByDate();
}

function sortByDate() {
  var tbody = document.querySelector("#cashflow tbody");
  var rows = [].slice.call(tbody.querySelectorAll("tr"));

  //Add a compare function to the compareFunction paramter that defines how to sort the array.
  rows = rows.sort((row1, row2) => {
    return parseInt(row1.firstElementChild.textContent) - parseInt(row2.firstElementChild.textContent)
  });

  rows.forEach(function(v) {
    tbody.appendChild(v);
  });
}
table {
  table-layout: fixed;
  empty-cells: show;
  font-family: Verdana, sans-serif;
  font-size: .8em;
  width: 100%;
  <!--874px;
  -->table-layout: fixed;
  overflow: hidden;
  white-space: nowrap;
  text-align: left;
  border: 1px solid black;
  border-collapse: collapse;
  padding: 5px;
}

th {
  padding: 3px;
  font-size: .84em;
}

td {
  padding: 3px;
  font-size: .9em;
}

tr:nth-child(odd) {
  background: #eee;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <button onclick="calcbal()">Sort 1st col</button>
  <table id=cashflow contenteditable>
    <thead>
      <tr>
        <th width="40px" contenteditable="false">Sortcell</th>
        <!--0-->
        <th width="115px" contenteditable="false">AccountName</th>
        <!--1-->
        <th width="40px" contenteditable="false">PayDate</th>
        <!--2-->
        <th width="40px" contenteditable="false">DueDate</th>
        <!--3-->
        <th width="32px" contenteditable="false">Cycle</th>
        <!--4-->
        <th width="34px" contenteditable="false">Method</td>
          <!--5-->
          <th width="41px" contenteditable="false">AutoPay</th>
          <!--6-->
          <th width="150px" contenteditable="false">Comment</th>
          <!--7-->
          <th width="45px" contenteditable="false">PymtDue</th>
          <!--8-->
          <th width="34px" contenteditable="false">Budget</th>
          <!--9-->
          <th width="66px" contenteditable="false">PymtSched</th>
          <!--10-->
          <th width="38px" contenteditable="false">Balance</th>
          <!--11-->
          <th width="200px" contenteditable="false">URL</th>
          <!--12-->
          <th width="39px" contenteditable="false">AcctBal</th>
          <!--13-->
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>200101</td>
        <td>Bank Account xxxx</td>
        <td>01/01/20</td>
        <td>01/01/20</td>
        <td>None</td>
        <td>None</td>
        <td>None</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td>https://www.</td>
        <td>1000</td>
      </tr>
      <tr>
        <td>210401</td>
        <td>APLACE4SPACE</td>
        <td>04/01/21</td>
        <td>04/01/21</td>
        <td>Monthly</td>
        <td>Online</td>
        <td>None</td>
        <td></td>
        <td>79</td>
        <td></td>
        <td>79</td>
        <td></td>
        <td>https://www.aplace4space.com/</td>
        <td>0</td>
      </tr>
      <tr>
        <td>210331</td>
        <td>RENT TO DOUG</td>
        <td>03/31/21</td>
        <td>03/31/21</td>
        <td>None</td>
        <td>None</td>
        <td>None</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td>https://www.</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>
</body>

</html>

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

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.