1

Attempting to sort a table by clicking the headers as found on W3Schools: https://www.w3schools.com/howto/howto_js_sort_table.asp However, the table is created from a spreadsheet and in a separate function. rows = coasterTable.rows; returns as undefined.

  function init() {
    Papa.parse(public_spreadsheet_url, {
      download: true,
      header: true,
      complete: makeTable
    })
  }

  window.addEventListener('DOMContentLoaded', init)
  
  function makeTable(results) {
    var data = results.data
    const newTable = document.createElement("table");
    newTable.innerHTML = '<thead><th onclick="sortTable(0)">Rank</th><th onclick="sortTable(1)">Coaster</th><th onclick="sortTable(2)">Park</th><th onclick="sortTable(3)">Manufacturer</th></thead>';
    var j = 0;
    while (j < data.length){
      const newRow = document.createElement("tr");
      const tdRank = document.createElement("td");
      const tdCoaster = document.createElement("td");
      const tdPark = document.createElement("td");
      const tdManu = document.createElement("td");
      tdRank.textContent = data[j].RANK;
      tdCoaster.textContent = data[j].COASTER;
      tdPark.textContent = data[j].PARK;    
      tdManu.textContent = data[j].MANUFACTURER;
      newRow.appendChild(tdRank);
      newRow.appendChild(tdCoaster);
      newRow.appendChild(tdPark);
      newRow.appendChild(tdManu);
      newTable.appendChild(newRow);
      j++;
    }

    const coasterTable = document.getElementById('coasterTable');
    coasterTable.appendChild(newTable);
  }
 
  document.write("spreadsheet link: <a target='_new' href='" + public_spreadsheet_url + "'>" + public_spreadsheet_url + "</a>");        

  function searchFunction() {
    // Declare variables
    var input, filter, coasterTable, tr, td1, td2, i, txtValue;
    input = document.getElementById("coasterInput");
    filter = input.value.toUpperCase();
    coasterTable = document.getElementById("coasterTable");
    tr = table.getElementsByTagName("tr");

    // Loop through all table rows, and hide those who don't match the search query
    for (i = 0; i < tr.length; i++) {
      td1 = tr[i].getElementsByTagName("td")[1];
      td2 = tr[i].getElementsByTagName("td")[2];
      if (td1 || td2) {
        txtValue1 = (td1.textContent || td1.innerText);
        txtValue2 = (td2.textContent || td2.innerText);
        if ((txtValue1.toUpperCase().indexOf(filter) > -1) || (txtValue2.toUpperCase().indexOf(filter) > -1)) {
          tr[i].style.display = "";
        } else {
          tr[i].style.display = "none";
        }
      }
    }
  }
  
  function sortTable(n) {
    var coasterTable, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
    coasterTable = document.getElementById("coasterTable");
    switching = true;
    // Set the sorting direction to ascending:
    dir = "asc";
    /* Make a loop that will continue until
    no switching has been done: */
    while (switching) {
      // Start by saying: no switching is done:
      switching = false;
      console.log(coasterTable);
      console.log(coasterTable.rows);
      rows = coasterTable.rows;                           /* -|- PROBLEM OCCURS HERE -|- */
      /* Loop through all table rows (except the
      first, which contains table headers): */
      for (i = 1; i < (rows.length - 1); i++) {            /* -|- PROBLEM OCCURS HERE -|- */
        // Start by saying there should be no switching:
        shouldSwitch = false;
        /* Get the two elements you want to compare,
        one from current row and one from the next: */
        x = rows[i].getElementsByTagName("TD")[n];
        y = rows[i + 1].getElementsByTagName("TD")[n];
        /* Check if the two rows should switch place,
        based on the direction, asc or desc: */
        if (dir == "asc") {
          if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
            // If so, mark as a switch and break the loop:
            shouldSwitch = true;
            break;
          }
        } else if (dir == "desc") {
          if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
            // If so, mark as a switch and break the loop:
            shouldSwitch = true;
            break;
          }
        }
      }
      if (shouldSwitch) {
        /* If a switch has been marked, make the switch
        and mark that a switch has been done: */
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        // Each time a switch is done, increase this count by 1:
        switchcount ++;
      } else {
        /* If no switching has been done AND the direction is "asc",
        set the direction to "desc" and run the while loop again. */
        if (switchcount == 0 && dir == "asc") {
          dir = "desc";
          switching = true;
        }
      }
    }
  }
</script>

This program reads a spreadsheet and displays it in a table using papaparse to parse through the data and put it into a table. This table can be searched through with a search bar. However, sorting by clicking on headers does not work. I am looking to fix this problem.

Attempted to change table names to correct for any misspellings, make sure that the table could be read and seen from inside the function. Used console commands to verify that the table is in fact being received by the line of code. Expecting for rows = coasterTable.rows; to return the rows of the table to allow for sorting.

Watkin81
  • 11
  • 2
  • not sure what you trying to do, but `coasterTable` is a html element and it does not have rows properties, that is why it returned `undefined` – Marcus.Aurelianus Jan 31 '23 at 06:39
  • That makes sense to me. How would I go about refering to the table (created with 'document.createElement') instead of the html element to be used inside of the sortTable function? – Watkin81 Jan 31 '23 at 18:32
  • you need to create a data model with js or use a library that support this – Marcus.Aurelianus Feb 01 '23 at 06:39

0 Answers0