How do I Multiply unit price and quantity for total price? - javascript

I have inputs like this -
<div id="multipleEntry">
<div class="d-flex">
<table class="table table-borderless">
<tbody>
<td>
<x-layouts.dropdowns name="product_id[]" title="Product" class="mt-2" id="productName" :dropItems="$products" :setItem="old('productName')" option1="Select Product" />
</td>
<td>
<x-layouts.input name="unitPrice[]" title="Unit Price" type="number" id="unitPrice" :value="111" />
</td>
<td>
<x-layouts.input name="quantity[]" title="Quantity" type="number" id="quantity" :value="old('quantity')" />
</td>
<td>
<x-layouts.input name="price[]" title="Price" type="number" id="price" :value="old('price')" />
</td>
</tbody>
</table>
</div>
</div>
<div class="col-sm-1 mb-3" id="controls">
<button class="btn btn-primary addNewBtn" type="button"><i class="fa-solid fa-plus"></i></button>
</div>
and for increment of columns I used -
const addNewBtn = document.querySelector(".addNewBtn");
const multipleEntry = document.querySelector("#multipleEntry");
addNewBtn.addEventListener("click", (e) => {
const lastRow = multipleEntry.lastElementChild;
let clone = lastRow.cloneNode(true);
multipleEntry.appendChild(clone);
});
I want to calculate the price and sub total price dynamically with javascript.
How do I do that?

I have modified your js function:
const addNewBtn = document.querySelector(".addNewBtn");
const multipleEntry = document.querySelector("#multipleEntry");
addNewBtn.addEventListener("click", (e) => {
let quantityArr = [];
let totalAmount = [];
const lastRow = multipleEntry.lastElementChild;
var length = document.getElementsByName('product_id[]').length;
var prices = document.getElementsByName('unitPrice[]');
var quantity = document.getElementsByName('quantity[]');
for (let i = 1; i <= length; i++) {
quantityArr.push(parseInt(quantity[i-1].value));
totalAmount.push(parseInt(quantity[i-1].value) * parseInt(prices[i-1].value));
}
console.log(totalAmount);
console.log(quantityArr);
let clone = lastRow.cloneNode(true);
multipleEntry.appendChild(clone);
});

Related

How to prevent changes for radio button input for duplicated row

I'm a beginner in JavaScript. I have a table row which consist of text input, radio buttons and button to add or delete the row. When I click the add button, it will duplicate the row exactly like the current one. However, when I click any of the radio button in second row (the duplicated row), my choice from the first row is changed/cleared. How can I solved this? And how can I save and export this HTML form to excel?
I have tried all methods that I can find and even watched YouTube videos. Any suggestion to improve my code are welcome. Thank you.
function addRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').insertRow(i + 1);
tr.innerHTML = row.parentNode.parentNode.innerHTML;
var inputs = tr.querySelectorAll("input[type='text']");
for (var i = 0; i < inputs.length; i++)
inputs[i].value = "";
}
function delRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').deleteRow(i - 1);
tr.innerHTML = row.parentNode.parentNode.innerHTML;
var inputs = tr.querySelectorAll("input[type='text']");
for (var i = 0; i < inputs.length; i--)
inputs[i].value = "";
}
<div style="overflow-x:auto;">
<table id="Table" style="width: 100%">
<tr>
<td><input type="text" name="questions" size="80" id="questions" placeholder="Questions" required/><br><br>
<input type="radio" name="smiley" value="rd1">&#128542 I don't like it at all.<br>
<input type="radio" name="smiley" value="rd2">&#128533 I maybe like it.<br>
<input type="radio" name="smiley" value="rd3">&#128578 I like it.<br>
<input type="radio" name="smiley" value="rd4">&#128516 I like it very much.<br><br>
<input type="button" id="addBtn" value="Add Questions" onclick="addRow(this)" value="1" />
<input type="button" id="delBtn" value="Delete Questions" onclick="delRow(this)" value="1" />
</td>
</tr>
</table>
</div>
You can see how to download csv from html table here
As for your code, you need to change the name of the input for the new row.
function addRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').insertRow(i + 1);
tr.innerHTML = row.parentNode.parentNode.innerHTML.replace(/smiley/g, "smiley" + i);
var inputs = tr.querySelectorAll("input[type='text']");
for (var i = 0; i < inputs.length; i++)
inputs[i].value = "";
}
function delRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').deleteRow(i - 1);
tr.innerHTML = row.parentNode.parentNode.innerHTML;
var inputs = tr.querySelectorAll("input[type='text']");
for (var i = 0; i < inputs.length; i--)
inputs[i].value = "";
}
<div style="overflow-x:auto;">
<table id="Table" style="width: 100%">
<tr>
<td><input type="text" name="questions" size="80" id="questions" placeholder="Questions" required/><br><br>
<label><input type="radio" name="smiley" value="rd1">&#128542 I don't like it at all.</label><br>
<label><input type="radio" name="smiley" value="rd2">&#128533 I maybe like it.</label><br>
<label><input type="radio" name="smiley" value="rd3">&#128578 I like it.</label><br>
<label><input type="radio" name="smiley" value="rd4">&#128516 I like it very much.<br></label><br>
<input type="button" id="addBtn" value="Add Questions" onclick="addRow(this)" value="1" />
<input type="button" id="delBtn" value="Delete Questions" onclick="delRow(this)" value="1" />
</td>
</tr>
</table>
</div>
Different radio button groups need different names. I tweaked your JS to add a unique timestamp to the radio button name when adding a new row.
function addRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').insertRow(i + 1);
tr.innerHTML = row.parentNode.parentNode.innerHTML;
var inputs = tr.querySelectorAll("input[type='text']");
for (var i = 0; i < inputs.length; i++)
inputs[i].value = "";
const unique= Date.now();
const radios = tr.querySelectorAll("input[type='radio']");
for (var i = 0; i < radios.length; i++)
radios[i].name = `${radios[i].name}${unique}`;
}
function delRow(row) {
var i = row.parentNode.parentNode.rowIndex;
var tr = document.getElementById('Table').deleteRow(i);
}
<div style="overflow-x:auto;">
<table id="Table" style="width: 100%">
<tr>
<td><input type="text" name="questions" size="80" id="questions" placeholder="Questions" required/><br><br>
<input type="radio" name="smiley" value="rd1">&#128542 I don't like it at all.<br>
<input type="radio" name="smiley" value="rd2">&#128533 I maybe like it.<br>
<input type="radio" name="smiley" value="rd3">&#128578 I like it.<br>
<input type="radio" name="smiley" value="rd4">&#128516 I like it very much.<br><br>
<input type="button" id="addBtn" value="Add Questions" onclick="addRow(this)" value="1" />
<input type="button" id="delBtn" value="Delete Questions" onclick="delRow(this)" value="1" />
</td>
</tr>
</table>
</div>
I would delegate and clone
NOTE I changed the id to a class for the buttons and added a tbody
You must have unique IDs
I renumber all the radios from 1 to n even when you delete a row in the middle
I also hide the first delete using CSS
const tb = document.getElementById("Table");
const firstRow = tb.querySelector("tr")
tb.addEventListener("click", e => {
const tgt = e.target;
if (!tgt.type === "button") return; // not a button
if (tgt.matches(".addBtn")) tb.append(firstRow.cloneNode(true)); // clone the first row
else if (tgt.matches(".delBtn")) tgt.closest("tr").remove();
// rename radios
tb.querySelectorAll("tr").forEach((tr,i) => {
tr.querySelectorAll("input[type=radio]").forEach(rad => rad.name = `question${i+1}`)
})
})
#Table tr:first-child .delBtn { display: none; }
<div style="overflow-x:auto;">
<table style="width: 100%">
<tbody id="Table">
<tr>
<td><input type="text" name="questions" size="80" placeholder="Questions" required/><br><br>
<input type="radio" name="question1" value="rd1">&#128542 I don't like it at all.<br>
<input type="radio" name="question1" value="rd2">&#128533 I maybe like it.<br>
<input type="radio" name="question1" value="rd3">&#128578 I like it.<br>
<input type="radio" name="question1" value="rd4">&#128516 I like it very much.<br><br>
<input type="button" class="addBtn" value="Add Questions" value="1" />
<input type="button" class="delBtn" value="Delete Questions" value="1" />
</td>
</tr>
</tbody>
</table>
</div>

how to fix: Cannot read property 'value' of undefined

I am trying to get the value of the quantityElement so i can make the price change decrease/increase when the quantity goes down/up but i order for this to work i need to get the value of the quantityElement which keeps coming back as undefined in the console.
var removeCartitemButtons = document.getElementsByClassName('remove-btn')
console.log(removeCartitemButtons)
for (var i = 0; i < removeCartitemButtons.length; i++) {
var button = removeCartitemButtons[i]
button.addEventListener('click', function(event) {
console.log('clicked')
var buttonClicked = event.target
buttonClicked.parentElement.parentElement.remove()
updateCartTotal()
})
}
// Update Cart total price
function updateCartTotal() {
var cartItemContainer = document.getElementsByClassName('cart-items')[0]
var cartRows = cartItemContainer.getElementsByClassName('cart-info')
for (var i = 0; i < cartRows.length; i++) {
var cartRow = cartRows[i]
var priceElement = cartRow.getElementsByClassName('product-price')[0]
var quantityElement = cartRow.getElementsByClassName('quantity-value')
[0]
var price = parseFloat(priceElement.innerText.replace('R', ''))
var quantity = quantityElement.value
console.log(price * quantity)
}
}
<td>
<div class="cart-items">
<div class="cart-info">
<img src="images/men3(balenciaga).png" width="250px">
<span class="product-price">R7400</span>
</div>
<span class="cart-item-title">Balenciaga Speed High</span>
</div>
<br>
<button class="remove-btn" type="button">Remove</button>
</div>
</div>
</div>
</td>
<td><input class="quantity-value" type="number" value="1"></td>
</tr>
You are trying to get 'quantity-value' field inside cartRow, but it does not exist inside the 'cart-info' div, because of which you are getting this value as undefined.
var quantityElement = cartRow.getElementsByClassName('quantity-value')[0]
Your html should probably be like below:
var removeCartitemButtons = document.getElementsByClassName('remove-btn')
console.log(removeCartitemButtons)
for (var i = 0; i < removeCartitemButtons.length; i++) {
var button = removeCartitemButtons[i]
button.addEventListener('click', function(event) {
console.log('clicked')
var buttonClicked = event.target
buttonClicked.parentElement.remove()
// updateCartTotal()
})
}
<td>
<div class="cart-items">
<div class="cart-info">
<img src="images/men3(balenciaga).png" width="450px">
<span class="product-price">R7401</span>
<input class="quantity-value" type="number" value="1">
</div>
<span class="cart-item-title">Balenciaga Speed High1</span>
<button class="remove-btn" type="button">Remove1</button>
</div>
</td>
<td>
<div class="cart-items">
<div class="cart-info">
<img src="images/men3(balenciaga).png" width="450px">
<span class="product-price">R7402</span>
<input class="quantity-value" type="number" value="2">
</div>
<span class="cart-item-title">Balenciaga Speed High2</span>
<button class="remove-btn" type="button">Remove2</button>
</div>
</td>
<td>
<div class="cart-items">
<div class="cart-info">
<img src="images/men3(balenciaga).png" width="450px">
<span class="product-price">R7403</span>
<input class="quantity-value" type="number" value="3">
</div>
<span class="cart-item-title">Balenciaga Speed High3</span>
<button class="remove-btn" type="button">Remove3</button>
</div>
</td>

Array output for each table cell

This is a table for user to record Expenses and Amount. User can add table cell to record more items with the amount. After user key in the Amount, it will show 7% tax at beside and total amount at the top. But now i am facing 2 problems.
If user added 2 items, and input the 2 items' amount, then if they deleted the row, the total amount will not deduct after the row is deleted.
the tax will only added in first row. I want to do it in each row with 7% tax with each item's amount.
So can i know how to solve this 2 problems?
function validate(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
//<----------------------2 Decimal force END-------------------->
// +
function mFunction() {
document.getElementById("rowrow").insertRow(-1).innerHTML =
'<tr><td></td><td><output id="gst">0.00</output></td><td><input type="text" name="Amount[]" id="columninput" class="input" oninput="myFunction(this.value)" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress="validate(event)" inputmode="numeric"></td></tr>';
}
// -
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
document.getElementById("rowrow").deleteRow(-1);
};
}
function myFunction() {
const ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById('gst').textContent = (sum * 0.07).toFixed(2);
}
.css-serial {
counter-reset: serial-number;
}
.css-serial td:first-child:before {
counter-increment: serial-number;
content: counter(serial-number);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<div id="container">
<div id="body">
<br>
<div class="row">
<div class="css-serial" style="overflow-x:auto;">
<table id="rowrow">
<tr>
<td id="number"></td>
<td><output id="gst">0.00</output></td>
<td><input type="text" name="Amount[]" class="input" oninput="myFunction(this.value)" id="columninput" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress='validate(event)' inputmode='numeric'
required></td>
Total Amount <output id="result"> 0.00 </output>
<input type="button" id="slipbutton1" onclick="mFunction();" name='add' value="+" />
<input type="button" id="slipbutton2" onclick="remove();" name='remove' value="-" /><br><br>
</table>
</div>
</div>
<br>
</div>
</div>
I have managed to make changes as per your need, also I have used jquery as you had added into your code.
I have calculated output in the remove() you can move it to a common function to avoid dirty code.
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
sum = sum - ele[ele.length - 1].value;
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById("rowrow").deleteRow(-1);
};
}
Changed GST id to class, as id should be unique.
Added this line of code to print GST into each row.
$(input).parents("tr").find(".gst").text((input.value * 0.07).toFixed(2));
you had added 2 class attributes to input in JS template, also merged them.
<tr>
<td></td>
<td><output class="gst">0.00</output></td>
<td>
<input
type="text"
name="Amount[]"
class="columninput input" // This line
oninput="myFunction(this.value)"
placeholder="Amount"
style="font-size:14px;"
min="0" lang="en-150"
onchange="force2decimals(this)"
onkeypress="validate(event)"
inputmode="numeric"
>
</td>
</tr>
function validate(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
//<----------------------2 Decimal force END-------------------->
// +
function mFunction() {
document.getElementById("rowrow").insertRow(-1).innerHTML =
'<tr><td></td><td><output class="gst">0.00</output></td><td><input type="text" name="Amount[]" class="columninput input" oninput="myFunction(this.value)" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress="validate(event)" inputmode="numeric"></td></tr>';
}
// -
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
sum = sum - ele[ele.length - 1].value;
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById("rowrow").deleteRow(-1);
};
}
function myFunction() {
debugger
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
$(input).parents("tr").find(".gst").text((input.value * 0.07).toFixed(2));
});
document.getElementById('result').textContent = sum.toFixed(2);
//document.getElementById('gst').textContent = (sum * 0.07).toFixed(2);
}
.css-serial {
counter-reset: serial-number;
}
.css-serial td:first-child:before {
counter-increment: serial-number;
content: counter(serial-number);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="body">
<br>
<div class="row">
<div class="css-serial" style="overflow-x:auto;">
<table id="rowrow">
<tr>
<td id="number"></td>
<td><output class="gst">0.00</output></td>
<td><input type="text" name="Amount[]" class="input" oninput="myFunction(this.value)" id="columninput" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress='validate(event)' inputmode='numeric'
required></td>
Total Amount <output id="result"> 0.00 </output>
<input type="button" id="slipbutton1" onclick="mFunction();" name='add' value="+" />
<input type="button" id="slipbutton2" onclick="remove();" name='remove' value="-" /><br><br>
</table>
</div>
</div>
<br>
</div>
</div>

Delete Item in Javascript

The first question is I need help in delete function. I already tried the splice method but I still can't get it. When you click the delete item button, that row must be deleted.
The second question has ii already put the required attribute in the input form but it still submits the form when the field is empty.
var qtyTotal = 0;
var priceTotal = 0;
var products = [];
function addProduct() {
var productID = document.getElementById("productID").value;
var product_desc = document.getElementById("product_desc").value;
var qty = document.getElementById("quantity").value;
// qtyTotal = qtyTotal + parseInt(qty);
//document.getElementById("qtyTotals").innerHTML=qtyTotal;
var price = document.getElementById("price").value;
var newProduct = {
product_id : null,
product_desc : null,
product_qty : 0,
product_price : 0.00,
};
newProduct.product_id = productID;
newProduct.product_desc = product_desc;
newProduct.product_qty = qty;
newProduct.product_price = price;
products.push(newProduct);
//console.log("New Product " + JSON.stringify(newProduct))
//console.log("Products " + JSON.stringify(products))
var html = "<table border='1|1' >";
html+="<td>Product ID</td>";
html+="<td>Product Description</td>";
html+="<td>Quantity</td>";
html+="<td>Price</td>";
html+="<td>Action</td>";
for (var i = 0; i < products.length; i++) {
html+="<tr>";
html+="<td>"+products[i].product_id+"</td>";
html+="<td>"+products[i].product_desc+"</td>";
html+="<td>"+products[i].product_qty+"</td>";
html+="<td>"+products[i].product_price+"</td>";
html+="<td><button type='submit' onClick='deleteProduct();'/>Delete Item</button> &nbsp <button type='submit' onClick='addCart();'/>Add to Cart</button></td>";
html+="</tr>";
}
html+="</table>";
document.getElementById("demo").innerHTML = html;
document.getElementById("resetbtn").click()
}
function deleteProduct(product_id) {
for(var i = 0; i < products.length; i++) {
if (products[i].product_id == product_id) {
// DO NOT CHANGE THE 1 HERE
products.splice(i, 1);
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart Pure Javascript</title>
</head>
<body>
<form name="order" id="order">
<table>
<tr>
<td>
<label for="productID">Product ID:</label>
</td>
<td>
<input id="productID" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="product">Product Desc:</label>
</td>
<td>
<input id="product_desc" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="quantity">Quantity:</label>
</td>
<td>
<input id="quantity" name="quantity" width="196px" required/>
</td>
</tr>
<tr>
<td>
<label for="price">Price:</label>
</td>
<td>
<input id="price" name="price" size="28" required/>
</td>
</tr>
</table>
<input type="reset" name="reset" id="resetbtn" class="resetbtn" value="Reset" />
<input type="button" id="btnAddProduct" onclick="addProduct();" value="Add New Product" >
</form>
<br>
<p id="demo"></p>
</body>
</html>
Firstly, you will have to pass correct product_id to delete function. Also you need to know which element to remove, for this you can send the current element on which click is pressed and then access its parent node to remove it. You can replace your script with following code:
var qtyTotal = 0;
var priceTotal = 0;
var products = [];
function addProduct() {
var productID = document.getElementById("productID").value;
var product_desc = document.getElementById("product_desc").value;
var qty = document.getElementById("quantity").value;
// qtyTotal = qtyTotal + parseInt(qty);
//document.getElementById("qtyTotals").innerHTML=qtyTotal;
var price = document.getElementById("price").value;
var newProduct = {
product_id : null,
product_desc : null,
product_qty : 0,
product_price : 0.00,
};
newProduct.product_id = productID;
newProduct.product_desc = product_desc;
newProduct.product_qty = qty;
newProduct.product_price = price;
products.push(newProduct);
//console.log("New Product " + JSON.stringify(newProduct))
//console.log("Products " + JSON.stringify(products))
var html = "<table id='products-table' border='1|1' >";
html+="<td>Product ID</td>";
html+="<td>Product Description</td>";
html+="<td>Quantity</td>";
html+="<td>Price</td>";
html+="<td>Action</td>";
for (var i = 0; i < products.length; i++) {
html+="<tr>";
html+="<td>"+products[i].product_id+"</td>";
html+="<td>"+products[i].product_desc+"</td>";
html+="<td>"+products[i].product_qty+"</td>";
html+="<td>"+products[i].product_price+"</td>";
html+="<td><button type='submit' onClick='deleteProduct(\""+products[i].product_id +"\", this);'/>Delete Item</button> &nbsp <button type='submit' onClick='addCart();'/>Add to Cart</button></td>";
html+="</tr>";
}
html+="</table>";
document.getElementById("demo").innerHTML = html;
document.getElementById("resetbtn").click()
}
function deleteProduct(product_id, e) {
var pTbody = e.parentNode.parentNode.parentNode;
var pTable = pTbody.parentNode;
if((pTbody.children).length === 2)
pTable.parentNode.removeChild(pTable);
else
pTbody.removeChild(e.parentNode.parentNode);
for(var i = 0; i < products.length; i++) {
if (products[i].product_id == product_id) {
// DO NOT CHANGE THE 1 HERE
products.splice(i, 1);
}
}
}
Your main problem is that you're not passing the product id to the delete function, and you are expecting it on it.
Also, you can remove the HTML element itself.
I've done this snippet. I've added the product id as a the id for the row element of the table, so on your delete function you can remove it looking for that id.
Also, if the item to delete is the last on the table, the table will be removed too (I've added an id to the table so you can easily remove it)
var qtyTotal = 0;
var priceTotal = 0;
var products = [];
function addProduct() {
var productID = document.getElementById("productID").value;
var product_desc = document.getElementById("product_desc").value;
var qty = document.getElementById("quantity").value;
// qtyTotal = qtyTotal + parseInt(qty);
//document.getElementById("qtyTotals").innerHTML=qtyTotal;
var price = document.getElementById("price").value;
var newProduct = {
product_id : null,
product_desc : null,
product_qty : 0,
product_price : 0.00,
};
newProduct.product_id = productID;
newProduct.product_desc = product_desc;
newProduct.product_qty = qty;
newProduct.product_price = price;
products.push(newProduct);
//console.log("New Product " + JSON.stringify(newProduct))
//console.log("Products " + JSON.stringify(products))
var html = "<table id='products-table' border='1|1' >";
html+="<td>Product ID</td>";
html+="<td>Product Description</td>";
html+="<td>Quantity</td>";
html+="<td>Price</td>";
html+="<td>Action</td>";
for (var i = 0; i < products.length; i++) {
html+="<tr id='"+products[i].product_id+"'>";
html+="<td>"+products[i].product_id+"</td>";
html+="<td>"+products[i].product_desc+"</td>";
html+="<td>"+products[i].product_qty+"</td>";
html+="<td>"+products[i].product_price+"</td>";
html+="<td><button type='submit' onClick='deleteProduct("+products[i].product_id+");'/>Delete Item</button> &nbsp <button type='submit' onClick='addCart();'/>Add to Cart</button></td>";
html+="</tr>";
}
html+="</table>";
document.getElementById("demo").innerHTML = html;
document.getElementById("resetbtn").click()
}
function deleteProduct(product_id) {
for(var i = 0; i < products.length; i++) {
if (products[i].product_id == product_id) {
// DO NOT CHANGE THE 1 HERE
products.splice(i, 1);
var element = document.getElementById(product_id);
var tableElement = document.getElementById('products-table');
if(!products.length)
tableElement.parentNode.removeChild(tableElement);
else
tableElement.removeChild(element);
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart Pure Javascript</title>
</head>
<body>
<form name="order" id="order">
<table>
<tr>
<td>
<label for="productID">Product ID:</label>
</td>
<td>
<input id="productID" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="product">Product Desc:</label>
</td>
<td>
<input id="product_desc" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="quantity">Quantity:</label>
</td>
<td>
<input id="quantity" name="quantity" width="196px" required/>
</td>
</tr>
<tr>
<td>
<label for="price">Price:</label>
</td>
<td>
<input id="price" name="price" size="28" required/>
</td>
</tr>
</table>
<input type="reset" name="reset" id="resetbtn" class="resetbtn" value="Reset" />
<input type="button" id="btnAddProduct" onclick="addProduct();" value="Add New Product" >
</form>
<br>
<p id="demo"></p>
</body>
</html>
Hope this helps!
The problem is that you are modifying the array of products without actually changing the HTML displayed on the page.
If you added code to delete the specified table element, I believe the problem would be solved.
For instance:
You could attach an id that corresponds to product_id to each table when it's created, and then delete the table with that id.
var remove = document.getElementById(product_id);
remove.parentElement.removeChild(remove);
Your click handler is calling deleteProduct() which will call your function without passing a product_id value as a parameter so your if (products[i].product_id == product_id) will never evaluate to be true.
Try this:
html+="<td><button type='submit' onClick='deleteProduct(\""+products[i].product_id +"\");'/>Delete Item</button> <button type='submit' onClick='addCart();'/>Add to Cart</button></td>";
As far as the required fields make sure you have the type attribute set on all of your inputs and move <p id="demo"></p> inside of your form.
You must change delete button type from submit to button and you must add products[i].product_id paramater for deleteProduct function
html+="<td><button type='button' onClick='deleteProduct("+products[i].product_id+");'/>Delete Item</button> &nbsp <button type='submit' onClick='addCart();'/>Add to Cart</button></td>";

Looping through and storing each table row td element value as array of objects

I have a table that dynamically calculates and create new row. Here is a snippet of the:
<table>
<tr class="purchase_schedule_table">
<td><input type="text" name="purchase_place" class="purchase_place_info" style="width: 90%;" ></td>
<td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch_info" ></td>
<td><input type="number" name="frequency" style="width: 90%;" class="frequency" ></td>
<td><input type="number" name="low" style="width: 90%;" class="product_low" ></td>
<td><input type="number" name="high" style="width: 90%;" class="product_high" ></td>
<td><input type="number" name="average" style="width: 90%;" class="product_average" disabled ></td>
<td>
<div class = "input-group" id="addrow">
<input type="number" name="product_total" style="width: 90%;" class="product_total" disabled>
<span class = "input-group-addon" style="width:1%; background-color:#786bae;border-color:#786bae;">
<a href="#">
<span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-plus addrow" aria-hidden="true"></span>
</a>
</span>
</div>
</td>
</tr>
</table>
Here is a snippet of jquery code to calculate the values:
//calculate purchase schedule monthly total
function calculatePurchaseScheduleMonthlyTotal(){
var total_sum = 0;
$('.product_total').each(function () {
var value = $(this).val();
total_sum = parseInt(total_sum) + parseInt(value);
});
$('.total_sum').val(total_sum);
};
//calculate purchase schedule
function calculatePurchaseSchedule(ObjRow) {
var low = 0;
var high = 0;
var average = 0;
var frequency = 0;
var total = 0;
var total_sum = 0;
frequency = ($(ObjRow).find('.frequency').val() == "") ? 0 : $(ObjRow).find('.frequency').val();
high = ($(ObjRow).find('.product_high').val() == "") ? 0 : $(ObjRow).find('.product_high').val();
low = ($(ObjRow).find('.product_low').val() == "") ? 0 : $(ObjRow).find('.product_low').val();
average = (parseInt(high) + parseInt(low)) / 2;
total = average * frequency;
$(ObjRow).find('.product_total').val(total);
$(ObjRow).find('.product_average').val(average);
calculatePurchaseScheduleMonthlyTotal();
};
Here is also a snippet of the code that is use to trigger the calculation:
$(document).on('focusout','input[type=number]',function () {
calculatePurchaseSchedule($(this).closest('tr'));
saveData();
});
Here is the code for adding a table row dynamically:
$('#addrow').click(function (e) {
e.preventDefault();
var purchase_schedule_row = '<tr class="purchase_schedule_table"><td> <input type="text" name="purchase_place" class="purchase_place" style="width: 90%;"></td><td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch"></td><td><input type="number" name="frequency" style="width: 90%;" class="frequency"></td><td><input type="number" name="low" style="width: 90%;" class="product_low"></td> <td><input type="number" name="high" style="width: 90%;" class="product_high"></td> <td><input type="number" name="average" style="width: 90%;" class="product_average" disabled></td><td> <div class = "input-group" id="addrow"> <input type="number" name="total" style="width: 90%;" class="product_total" disabled><span class = "input-group-addon" style="width:1%; background-color:#ec6d65;border-color:#ec6d65;"> <span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-minus deleterow" aria-hidden="true"></span></span></div></td></tr>';
$('#purchaseScheduleTable').append(purchase_schedule_row);
});
What I want to do is to store each table row td element value as a array of objects. I have tried doing so in the following code:
var purchase_place;
var main_products_purch;
var frequency;
var product_low;
var product_high;
var product_average;
var product_total;
var product_total_sum;
var purchase_schedule_table = [];
var purchase_schedule_data = {};
var count = 1;
$('.purchase_schedule_table').each(function(){
$(this).find('.product_total').each(function () {
product_total = $(this).find('.product_total').val();
console.log(product_total);
purchase_schedule_data.product_total = product_total;
});
purchase_schedule_table.push(purchase_schedule_data);
});
console.log(purchase_schedule_table);
For example, the end result should be like this:
[
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
]
What am I doing wrong? Thanks in advance.
Iterate through each tr with class purchase_schedule_table and then each td in it, make an object and push it in a an array like following.
var arr = [];
$('.purchase_schedule_table').each(function () {
var obj = {};
$(this).find('td').each(function () {
var input = $(this).find('input')[0];
obj[input.name] = input.value;
});
arr.push(obj);
})
console.log(arr)

Categories