1

I have a table with cells that are not contentEditable. However, using a JavaScript loop or function, I would like to make them so.

I understand that it is very simple to do this manually for each cell, and this would probably be easier for a table with only a few cells, but I would like to quicken this process with a loop/function for the table could become much larger, and the time spent manually setting each cell to be contentEditable would be tedious.

Below is a quick example that displays a table calculator, un-editable at present. But using a loop or function, I'd like to make every cell in the right column set to .contentEditable = true in the DOM. I imagine that the parameters would look something like (var i = 0; l != rows.length; i < l; i+2), but I'm struggling with what the statements following the argument would have to be for the loop/function to work. Any help would be much appreciated!

function myFunction() {
  var jack2 = document.getElementById("jack").innerText;
  var john2 = document.getElementById("john").innerText;
  var joe2 = document.getElementById("joe").innerText;

  var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);

  document.getElementById("total").innerHTML = total2;
}
table {
  width: 100%;
}

table,
tr,
th,
td {
  border: 1px solid gray;
  border-collapse: collapse;
  font-family: Arial;
  margin: 5px;
}
<table>
  <caption>Weight Calculator</caption>
  <tr class="cell">
    <th>Person</th>
    <th>Weight (kg)</th>
  </tr>
  <tr class="cell">
    <td>Jack</td>
    <td id="jack" oninput="myFunction()">1</td>
  </tr>
  <tr class="cell">
    <td>John</td>
    <td id="john" oninput="myFunction()">2</td>
  </tr>
  <tr class="cell">
    <td>Joe</td>
    <td id="joe" oninput="myFunction()">3</td>
  </tr>
  <tr class="cell">
    <td>Total</td>
    <td id="total"></td>
  </tr>
</table>

2 Answers 2

1

Get all cell in the tabel that have a left neigbour (the header is not effected because there are th and not td). Add to each of these cells your attribute.

Edited: For getting the totalsum add an eventlistener on each td that calls the calc-function if the content changes.

function myFunction() {
    let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
    weightCells.forEach(td => {
        td.setAttribute('contentEditable', true);
        td.addEventListener ("change", calcSum());
    });
}

function calcSum() {
    let sum=0;
    let weightCells = document.querySelectorAll("table tr td ~ td");
    let count = weightCells.length-1;
    for (i=0; i<count; i++) {
        sum +=  parseInt(weightCells[i].innerHTML) || 0;
    }
  weightCells[count].innerHTML = sum;
}

myFunction();
table {
  width: 100%;
}

table,
tr,
th,
td {
  border: 1px solid gray;
  border-collapse: collapse;
  font-family: Arial;
  margin: 5px;
}
<table>
  <caption>Weight Calculator</caption>
  <tr class="cell">
    <th>Person</th>
    <th>Weight (kg)</th>
  </tr>
  <tr class="cell">
    <td>Jack</td>
    <td id="jack" oninput="myFunction()">1</td>
  </tr>
  <tr class="cell">
    <td>John</td>
    <td id="john" oninput="myFunction()">2</td>
  </tr>
  <tr class="cell">
    <td>Joe</td>
    <td id="joe" oninput="myFunction()">3</td>
  </tr>
  <tr class="cell">
    <td>Total</td>
    <td id="total"></td>
  </tr>
</table>

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

Comments

1

You can select the whole table, then use querySelectorAll to get all rows then for each rows change the contenteditable for the second td like this

codepen

let table = document.getElementById('table')
let rows = table.querySelectorAll('tr')

rows.forEach(row => {
  let tds = row.querySelectorAll('td') 
  // all the cells of the row
  if (tds.length > 0) { // if it is not the header
    tds[1].contentEditable = true 
    // change the contenteditable
  }
})

(you need to add an id to your table in case you have more than one table)

<table id="table">
...
</table>

2 Comments

This is great, but it also makes the final cell editable. Is there a way to fix that?
Yes you can fix that look at my answer. The selector could be a little bit extended.

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.