1

I'm having an issue sorting my HTML table. The headers are clickable and they do sort, however it doesn't sort the table correctly. I'm using ACF Pro and FacetWP. The table is dynamic with PHP, need this to be able to sort alphanumerically. In theory this sort algorithm should work, but I'm not understanding why it's not sorting correctly. Any help would be greatly appreciated. Thank you!

cPrev = -1; // global var saves the previous c, used to
// determine if the same column is clicked again

function sortBy(c) {
  rows = document.getElementById("sortable").rows.length; // num of rows
  columns = document.getElementById("sortable").rows[0].cells.length; // num of columns
  arrTable = [...Array(rows)].map(e => Array(columns)); // create an empty 2d array

  for (ro = 0; ro < rows; ro++) { // cycle through rows
    for (co = 0; co < columns; co++) { // cycle through columns
      // assign the value in each row-column to a 2d array by row-column
      arrTable[ro][co] = document.getElementById("sortable").rows[ro].cells[co].innerHTML;
    }
  }

  th = arrTable.shift(); // remove the header row from the array, and save it

  if (c !== cPrev) { // different column is clicked, so sort by the new column
    arrTable.sort(
      function(a, b) {
        if (a[c] === b[c]) {
          return 0;
        } else {
          return (a[c] < b[c]) ? -1 : 1;
        }
      }
    );
  } else { // if the same column is clicked then reverse the array
    arrTable.reverse();
  }

  cPrev = c; // save in previous c

  arrTable.unshift(th); // put the header back in to the array

  // cycle through rows-columns placing values from the array back into the html table
  for (ro = 0; ro < rows; ro++) {
    for (co = 0; co < columns; co++) {
      document.getElementById("sortable").rows[ro].cells[co].innerHTML = arrTable[ro][co];
    }
  }
}
<body>
  <div style="overflow-x:auto;">
    <table id="sortable" style="width:100%;">
      <thead>
        <tr style="cursor:pointer">
          <th align="left">Address</th>
          <th onclick="sortBy(1)" align="left">City</th>
          <th onclick="sortBy(2)" align="left">State</th>
          <th onclick="sortBy(3)" align="left">Type</th>
          <th onclick="sortBy(4)" align="right">Available SF</th>
        </tr>
      </thead>
      <tbody id="table-body">
        <?php while ( have_posts() ): the_post(); ?>
        <tr>
          <td align="left">
            <a href="<?php the_permalink(); ?>">
              <?php the_field('building_address'); ?>
            </a>
          </td>
          <td align="left">
            <a href="<?php the_permalink(); ?>">
              <?php the_field('city'); ?>
            </a>
          </td>
          <td align="left">
            <a href="<?php the_permalink(); ?>">
              <?php the_field('state'); ?>
            </a>
          </td>
          <td align="left">
            <?php echo get_the_term_list($post->ID, 'property_type', '', ', '); ?>
          </td>
          <td align="right">
            <a href="<?php the_permalink(); ?>">
              <?php the_field('max_available_size'); ?>
            </a>
          </td>
        </tr>
        <?php endwhile; ?>
      </tbody>
    </table>
  </div>
</body>

3
  • what does it mean it doesn't sort correctly? Try replacing return (a[c] < b[c]) ? -1 : 1; with return (a[c]+'').localeCompare(b[c]); Commented Sep 16, 2020 at 16:44
  • Why php, ACF Pro or FacetWP? I've built an excellent and simple table sorter in pure JavaScript. Commented Sep 16, 2020 at 16:45
  • I'm working on a WordPress website Commented Sep 16, 2020 at 16:54

1 Answer 1

1

Here you can use this function I will explain below the code of passed function parameter:
colNo is pass number of column data wise sort data.
tableId is same as your table id sortable.
IsAsc variable value is true then rows set ascending order otherwise row set descending order.
example of function calling sortTable(1,"sortable",true).

function sortTable(colNo,tableId,IsAsc) {
          var table, rows, switching, i, x, y;
          table = document.getElementById(tableId);
          switching = true;
          while (switching) {
            switching = false;
            rows = table.rows;  
            for (i = 1; i < (rows.length - 1); i++) {
              if(rows[i].getElementsByTagName("TD")[colNo] != undefined && rows[i + 1].getElementsByTagName("TD")[colNo] != undefined)
              {
                x = rows[i].getElementsByTagName("TD")[colNo].innerHTML.toLowerCase();
                y = rows[i + 1].getElementsByTagName("TD")[colNo].innerHTML.toLowerCase();
                if ((x < y && IsAsc == false) || (x > y && IsAsc == true)) {
                  rows[i].parentNode.insertBefore(rows[i+1], rows[i]);
                  switching = true;
                  break;
                }
              }
            }    
          }
        }

Also this function used for sort data date,time,numbers,alphabats wise.


I took the liberty to add a snippet with your solutions.

function sortTable(colNo,tableId,IsAsc) {
          var table, rows, switching, i, x, y;
          table = document.getElementById(tableId);
          switching = true;
          while (switching) {
            switching = false;
            rows = table.rows;  
            for (i = 1; i < (rows.length - 1); i++) {
              if(rows[i].getElementsByTagName("TD")[colNo] != undefined && rows[i + 1].getElementsByTagName("TD")[colNo] != undefined)
              {
                x = rows[i].getElementsByTagName("TD")[colNo].innerHTML.toLowerCase();
                y = rows[i + 1].getElementsByTagName("TD")[colNo].innerHTML.toLowerCase();
                if ((x < y && IsAsc == false) || (x > y && IsAsc == true)) {
                  rows[i].parentNode.insertBefore(rows[i+1], rows[i]);
                  switching = true;
                  break;
                }
              }
            }    
          }
        }
  <table id="theTable" border="1">
    <thead>
      <tr>
        <th>
          <span>Header 1</span>
          <button onclick="sortTable(0,'theTable',true)">Asc</button>
          <button onclick="sortTable(0,'theTable',false)">Dsc</button>
        </th>
        <th>
          <span>Header 2</span>
          <button onclick="sortTable(1,'theTable',true)">Asc</button>
          <button onclick="sortTable(1,'theTable',false)">Dsc</button>
        </th>
        <th>
          <span>Header 3</span>
          <button onclick="sortTable(2,'theTable',true)">Asc</button>
          <button onclick="sortTable(2,'theTable',false)">Dsc</button>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Heavens</td>
        <td>and</td>
        <td>the</td>
      </tr><tr>
        <td>I</td>
        <td>created</td>
        <td>the</td>
      </tr><tr>
        <td>Took</td>
        <td>a</td>
        <td>nap</td>
      </tr><tr>
        <td>Earth</td>
        <td>Then</td>
        <td>I</td>
      </tr><tr>
        <td>At</td>
        <td>the</td>
        <td>begining</td>
      </tr>
      
      
      
      
    </tbody>
  </table>

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

3 Comments

IsAsc value true means row set in ascending order.fales means rows set in descending order.
Where is it stored? Anyways, when using true it sorts rows in descending order, and vice versa. Good job!
Perfect! You can remove the code quote, the horizontal line, and my line = leave the snippet instead.

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.