Home > Blockchain >  Checking if checkbox is checked: Uncaught TypeError
Checking if checkbox is checked: Uncaught TypeError

Time:11-16

I have a table with three columns: id, price and a checkbox. I want to parse the table to JSON but only include rows with a checked checkbox. However, my code throws Uncaught TypeError: Cannot read properties of undefined (reading 'type') in this line: if (ele[i].type == 'checkbox' && ele[i].checked == true). Where am I going wrong?

const btn = document.getElementById("click");
btn.addEventListener("click", function() {
  tableToJson(table);
})

let table = document.getElementById("myTable");

function tableToJson(table) {
  let data = [];
  const ele = document.querySelectorAll(".myCheckbox");
  // first row needs to be headers
  let headers = [];
  for (i = 0; i < table.rows[0].cells.length; i  ) {
    headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
  }

  // go through cells
  for (i = 1; i < table.rows.length; i  ) {
    if (ele[i].type == 'checkbox' && ele[i].checked == true) {
      let tableRow = table.rows[i];
      let rowData = {};

      for (j = 0; j < tableRow.cells.length; j  ) {

        rowData[headers[j]] = tableRow.cells[j].innerHTML;

      }

      data.push(rowData);
    }
  }
  console.log(data);
  return data;
}
<body>
  <button id="click">Click</button>
  <table id="myTable">
    <thead>
      <tr>
        <th>Id</th>
        <th>Price</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>AAA</td>
        <td>12.81</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>BBB</td>
        <td>1.06</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>CCC</td>
        <td>1.89</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>DDD</td>
        <td>1.94</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>EEE</td>
        <td>3.61</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
    </tbody>
  </table>
</body>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

As you're iterating on ele.length you should use ele[i].type == 'checkbox'.

Other than that, since you have 5 checkboxes and 6 rows, when you read tableRow you need to add a 1 otherwise you'll select the wrong row.

In your current code, if you select the first element (index 0) you get the header row (index 0) while you should take index 1 instead.

  let tableRow = table.rows[i 1];

const btn = document.getElementById("click");
btn.addEventListener("click", function() {
  tableToJson(table);
})

let table = document.getElementById("myTable");

function tableToJson(table) {
  let data = [];
  const ele = document.querySelectorAll(".myCheckbox");
  // first row needs to be headers
  let headers = [];
  for (i = 0; i < table.rows[0].cells.length; i  ) {
    headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
  }

  // go through cells
  for (i = 0; i < ele.length; i  ) {
    if (ele[i].type == 'checkbox' && ele[i].checked == true) {
      let tableRow = table.rows[i 1];
      let rowData = {};

      for (j = 0; j < tableRow.cells.length; j  ) {
        rowData[headers[j]] = tableRow.cells[j].innerHTML;
      }

      data.push(rowData);
    }
  }
  console.log(data);
  return data;
}
<body>
  <button id="click">Click</button>
  <table id="myTable">
    <thead>
      <tr>
        <th>Id</th>
        <th>Price</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>AAA</td>
        <td>12.81</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>BBB</td>
        <td>1.06</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>CCC</td>
        <td>1.89</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>DDD</td>
        <td>1.94</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
      <tr>
        <td>EEE</td>
        <td>3.61</td>
        <td><input type="checkbox" class="myCheckbox" checked></td>
      </tr>
    </tbody>
  </table>
</body>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

first I do not know where you aré importing your js. Second javascript Is faster than the dom so by the time you r js gets into if (ele[i].type == 'checkbox' && ele[i].checked == true) your dom Is not rendered yet. Thats y it breaks you need to wait for your dom to be rendered.

document.addEventLidtener("DOMContentLoaded", e=>{
// Add your code here
});
  • Related