I'm just working on a simple calculator for a small project of mine. I'm just hoping to get help with my calculatArea1 function.
I'll attach a few images showing the webpage, html code, and Javascript.
The html starts with a empty row with 3 cells so the user can add in the height and width of the window. Then, there's a button that allows the user to add a new row/window. This is all working fine.
The problem I'm having is, whenever I add multiple rows, then start adding in the width & height then click calculate it will only calculate the top row.
I though I might add also, if I start fresh with one row, then add the height & width, then click calculate. Then, click add window, then add the width & height, then calculate again. it works.
I just want to be able to add in as many rows as I need, then add in the data, then click calculate.
Any suggestions would be much appreciated, cheers!
HTML
<table id="table1">
<tr>
<th>Height</th>
<th>Width</th>
<th>Area</th>
</tr>
<tr>
<td><input class="height" type="text"></td>
<td><input class="width" type="text"></td>
<td><div class="area"></div></td>
</tr>
</table>
This is my Javascript functions
function addWindow1() {
var table1 = document.getElementById("table1");
var row1 = table1.insertRow(1);
var cell1 = row1.insertCell(0);
var cell2 = row1.insertCell(1);
var cell3 = row1.insertCell(2);
cell1.innerHTML = '<input class="height" type="text">';
cell2.innerHTML = '<input class="width" type="text">';
cell3.innerHTML = '<div class="area"></div>';
};
function calculateArea1() {
var table1 = document.getElementById("table1");
for(var i = 0; row = table1.rows[i]; i++){
var height = document.querySelector('.height').value;
var width = document.querySelector('.width').value;
var area = document.querySelector('.area');
var areaResult = height * width;
area.innerHTML = areaResult;
};
};
This is what happens if I add multiple rows first, then add in the width & height, then click calculate
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)
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With