Search code examples
javascripthtmlonchangeappendchild

When creating an <input> element, onchange after adding is not part of it


I added some elements to my table. There is a function to add (tr and td) those elements. Inside the function there is a part:

for(var i = 0; i < 4; i++) {
    cell = document.createElement("td");
    row.appendChild(cell);
    cellData = document.createElement("input");
    cellData.type = "number";
    cellData.min = "0"
    cellData.max = "7";
    cellData.value = "0";
    cellData.onchange = "calculate()";
    cell.appendChild(cellData);
}

This puts 4 cells with input field. My problem is, that the onchange part doesn't work. I know u can add onchange function to an input directly. But in this form it doesn't work. I know that cause when i checked it in the browser it skipped the onchange part:

<td><input type="number" min="0" max="7"></td>

It only added these. And also i didn't get my message from a the function:

function calculate() {
    console.log("something");
}

Can somebody give me a solution for this problem? Thank u for your time and answer!


Solution

  • Better

    cellData.onchange = calculate;
    

    Even better

    cellData.addEventListener("change",calculate);
    

    Best since it only has ONE event listener:

    document.querySelector("#myTable tbody").addEventListener("input",calculate);
    

    Example

    const getNum = str => isNaN(str) || str.trim() === "" ? 0 : +str;
    
    const tbody = document.querySelector("#myTable tbody");
    const totalSpan = document.getElementById('total');
    const calculate = fld => {
      const total = [...tbody.querySelectorAll("[type=number]")].map(fld => getNum(fld.value)).reduce((a, b) => a + b)
      totalSpan.textContent = total;
    };
    
    tbody.addEventListener("input", calculate);
    
    
    const row = document.createElement("tr")
    for (let i = 0; i < 4; i++) {
      cell = document.createElement("td");
      cellData = document.createElement("input");
      cellData.type = "number";
      cellData.min = "0"
      cellData.max = "7";
      cellData.value = "0";
      cell.appendChild(cellData);
      row.appendChild(cell);
    }
    tbody.appendChild(row);
    <table id="myTable">
      <tbody>
      </tbody>
    </table>
    <span id="total"></span>