Javascript function to calculate window areas in a table

Solution 1:

go to the add window button and add, onclick="addNewWindow()" then add this function

function addNewWindow(){
  let table = document.querySelectot('#table1');
  let window = `
    <tr>
      <td><input type="number" class="height"></td>
      <td><input type="number" class="width"></td>
      <td><input type="number" class="window" disabled style="user-select: select-all"></td>
    </tr>
  `;
  table.insertAdjacentHTML('beforeend', window)
}

then add the calculation functionality

var hinputs = document.querySelectorAll('.height');
var winputs = document.querySelectorAll('.width');
hinputs.foreach(h=>{
  h.addEventListener('change', ()=>{
    let width = h.parentElement.querySelector('.width');
    let window = h.parentElement.querySelector('.window');
    if(width.value !== ""){
      calculate(width.value, h.value, window )
    }
  })
})
winputs.foreach(w=>{
  w.addEventListener('change', ()=>{
    let height = w.parentElement.querySelector('.height ');
    let window = w.parentElement.querySelector('.window');
    if(height.value !== ""){
      calculate(w.value, height.value, window)
    }
  })
})

function calculate(w, h, result){
  result.value = w*h;
}

DEMO:

function addNewWindow() {
  let table = document.querySelector('#table');
  let window = `
    <tr>
      <td><input type="number" class="height"></td>
      <td><input type="number" class="width"></td>
      <td><input type="number" class="window" disabled style="user-select: select-all"></td>
    </tr>
  `;
  table.insertAdjacentHTML('beforeend', window)
}


var hinputs = document.querySelectorAll('.height');
var winputs = document.querySelectorAll('.width');
hinputs.forEach(h => {
  h.addEventListener('input', () => {
    let width = h.parentElement.parentElement.querySelector('.width');
    let window = h.parentElement.parentElement.querySelector('.window');
    if (width.value !== "") {
      calculate(width.value, h.value, window)
    }
  })
})
winputs.forEach(w => {
  w.addEventListener('input', () => {
    let height = w.parentElement.parentElement.querySelector('.height');
    let window = w.parentElement.parentElement.querySelector('.window');
    if (height.value !== "") {
      calculate(w.value, height.value, window)
    }
  })
})

function calculate(w, h, result) {
  result.value = w * h;
}
<table id="table">
  <tr>
    <td><input type="number" class="height"></td>
    <td><input type="number" class="width"></td>
    <td><input type="number" class="window" disabled style="user-select: select-all"></td>
  </tr>
  <tr>
    <td><input type="number" class="height"></td>
    <td><input type="number" class="width"></td>
    <td><input type="number" class="window" disabled style="user-select: select-all"></td>
  </tr>
</table>


<button onclick="addNewWindow()">add</button>

you can use ".innerHTML +=" or .insertAdjacentHTML('beforeend', '<div></div>');

but innerHTML removes the old inputs' values because it gets the old value and add to it your code then replace it with the current HTML so all manually applied values get removed, so use inserting beforeend to do it:

let table = document.querySelectot('#table1');
  let window = `
    <tr>
      <td><input type="number" class="height"></td>
      <td><input type="number" class="width"></td>
      <td><input type="number" class="window" disabled style="user-select: select-all"></td>
    </tr>
  `;
  table.insertAdjacentHTML('beforeend', window)

Solution 2:

You are only getting one element with querySelector inside the calculateArea1 function. You should loop over every row and update the area with the values of width and height of that row.

One way to do this is to give a class (lets say data) to rows that contain the width, height and area cells then loop over all elements with that data class and access the cells inside it with a querySelector.

You can simplify your addWindow1 function to this:

function addWindow1() {
  const row1 = table1.insertRow(1)
  row1.className = 'data'
  row1.innerHTML = `
      <td><input class="height" type="text" /></td>
      <td><input class="width" type="text" /></td>
      <td><div class="area"></div></td>
      `
}

Then update your calculateArea1 function as follows:

function calculateArea1() {
  const data = document.querySelectorAll('.data')

  for (let i = 0; i < data.length; i++) {
    const height = data[i].querySelector('.height').value
    const width = data[i].querySelector('.width').value
    data[i].querySelector('.area').textContent = height * width
  }
}

Here is a working example:

const add = document.getElementById('add')
const calc = document.getElementById('calc')
const table1 = document.getElementById('table1')

add.addEventListener('click', addWindow1)
calc.addEventListener('click', calculateArea1)

function addWindow1() {
  const row1 = table1.insertRow(1)
  row1.className = 'data'
  row1.innerHTML = `
      <td><input class="height" type="text" /></td>
      <td><input class="width" type="text" /></td>
      <td><div class="area"></div></td>
      `
}

function calculateArea1() {
  const data = document.querySelectorAll('.data')

  for (let i = 0; i < data.length; i++) {
    const height = data[i].querySelector('.height').value
    const width = data[i].querySelector('.width').value
    data[i].querySelector('.area').textContent = height * width
  }
}
<button id="add">add</button>
<button id="calc">calc</button>
<table id="table1">
  <tr>
    <th>Height</th>
    <th>Width</th>
    <th>Area</th>
  </tr>
  <tr class="data">
    <td><input class="height" type="text" /></td>
    <td><input class="width" type="text" /></td>
    <td>
      <div class="area"></div>
    </td>
  </tr>
</table>