How to integrate JavaScript into a HTML page - javascript

I am trying to make an HTML website that sells pens, pencils and erasers. My issue is integrating the JavaScript into my HTML page. Everything has been working properly up until the last couple chunks of JavaScript any thoughts on how I could fix this problem.
<!DOCTYPE html>
<html>
<head>
<title>Pens, Pencils and Erasers</title>
<meta name="description" content="This is the description">
<link rel="stylesheet" href="style.css" />
<script src="store.js" async></script>
</head>
<body>
<header class="main-header">
<nav class="main-nav nav">
<ul>
<li>HOME</li>
</ul>
</nav>
<h1 class="store-name store-name-large">Pens, Pencils and Erasers</h1>
</header>
<section class="container content-section">
<div class="shop-items">
<span class="shop-item-title">Pen</span>
<img class="shop-item-image" src="pen.jpg">
<div class="shop-item-details">
<span class="shop-item-price">$0.50</span>
<button class="btn btn-primary shop-item-button" type="button">ADD TO CART</button>
</div>
</div>
<div class="shop-item">
<span class="shop-item-title">Pencil</span>
<img class="shop-item-image" src="pencil.webp">
<div class="shop-item-details">
<span class="shop-item-price">$0.30</span>
<button class="btn btn-primary shop-item-button"type="button">ADD TO CART</button>
</div>
</div>
<div class="shop-item">
<span class="shop-item-title">Eraser</span>
<img class="shop-item-image" src="eraser.png">
<div class="shop-item-details">
<span class="shop-item-price">$1.00</span>
<button class="btn btn-primary shop-item-button" type="button">ADD TO CART</button>
</div>
</div>
</section>
<section class="container content-section">
<h2 class="section-header">CART</h2>
<select id = "province">
<option value= "saskatchewan" data-shipping-cost= "0" data-tax= "0.05" data-deal-limiter= "30" data-deal-coupon= "5">Saskatchewan</option>
<option value= "alberta" data-shipping-cost= "2" data-tax= "0.05" data-deal-limiter= "0" data-deal-coupon= "0">Alberta</option>
<option value= "manitoba" data-shipping-cost= "2" data-tax= "0.06" data-deal-limiter= "0" data-deal-coupon= "0">Manitoba</option>
</select>
<div class="cart-row">
<span class="cart-item cart-header cart-column">ITEM</span>
<span class="cart-price cart-header cart-column">PRICE</span>
<span class="cart-quantity cart-header cart-column">QUANTITY</span>
</div>
<div class="cart-items">
</div>
<div class="cart-total">
<strong class="cart-total-title">Total</strong>
<span class="cart-total-price">$0</span><br><br>
</div>
<button class="btn btn-primary btn-purchase" type="button">PURCHASE</button>
</section>
<script>
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready)
} else {
ready()
}
function ready() {
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
for (var i = 0; i < removeCartItemButtons.length; i++) {
var button = removeCartItemButtons[i]
button.addEventListener('click', removeCartItem)
}
var quantityInputs = document.getElementsByClassName('cart-quantity-input')
for (var i = 0; i < quantityInputs.length; i++) {
var input = quantityInputs[i]
input.addEventListener('change', quantityChanged)
}
var addToCartButtons = document.getElementsByClassName('shop-item-button')
for (var i = 0; i < addToCartButtons.length; i++) {
var button = addToCartButtons[i]
button.addEventListener('click', addToCartClicked)
}
document.getElementsByClassName('btn-purchase')[0].addEventListener('click', purchaseClicked)
}
function purchaseClicked() {
alert('Thank you for your purchase')
var cartItems = document.getElementsByClassName('cart-items')[0]
while (cartItems.hasChildNodes()) {
cartItems.removeChild(cartItems.firstChild)
}
updateCartTotal()
}
function removeCartItem(event) {
var buttonClicked = event.target
buttonClicked.parentElement.parentElement.remove()
updateCartTotal()
}
function quantityChanged(event) {
var input = event.target
if (isNaN(input.value) || input.value <= 0) {
input.value = 1
}
updateCartTotal()
}
function addToCartClicked(event) {
var button = event.target
var shopItem = button.parentElement.parentElement
var title = shopItem.getElementsByClassName('shop-item-title')[0].innerText
var price = shopItem.getElementsByClassName('shop-item-price')[0].innerText
var imageSrc = shopItem.getElementsByClassName('shop-item-image')[0].src
addItemToCart(title, price, imageSrc)
updateCartTotal()
}
function addItemToCart(title, price, imageSrc) {
var cartRow = document.createElement('div')
cartRow.classList.add('cart-row')
var cartItems = document.getElementsByClassName('cart-items')[0]
var cartItemNames = cartItems.getElementsByClassName('cart-item-title')
for (var i = 0; i < cartItemNames.length; i++) {
if (cartItemNames[i].innerText == title) {
alert('This item is already added to the cart')
return
}
}
var cartRowContents = `
<div class="cart-item cart-column">
<img class="cart-item-image" src="${imageSrc}" width="100" height="100">
<span class="cart-item-title">${title}</span>
</div>
<span class="cart-price cart-column">${price}</span>
<div class="cart-quantity cart-column">
<input class="cart-quantity-input" type="number" value="1">
<button class="btn btn-danger" type="button">REMOVE</button>
</div>`
cartRow.innerHTML = cartRowContents
cartItems.append(cartRow)
cartRow.getElementsByClassName('btn-danger')[0].addEventListener('click', removeCartItem)
cartRow.getElementsByClassName('cart-quantity-input')[0].addEventListener('change', quantityChanged)
}
function updateCartTotal() {
var cartItemContainer = document.getElementsByClassName('cart-items')[0]
var cartRows = cartItemContainer.getElementsByClassName('cart-row')
var order_total = 0
for (var i = 0; i < cartRows.length; i++) {
var cartRow = cartRows[i]
var priceElement = cartRow.getElementsByClassName('cart-price')[0]
var quantityElement = cartRow.getElementsByClassName('cart-quantity-input')[0]
var price = parseFloat(priceElement.innerText.replace('$', ''))
var quantity = quantityElement.value
order_total = order_total + (price * quantity)
}
order_total = Math.round(order_total * 100) / 100
document.getElementsByClassName('cart-total-price')[0].innerText = '$' + order_total
}
document.getElementById("province").addEventListener("change", function() {
const select = document.getElementById("province")
selectedProvince = select.options[select.selectedIndex]
shippingCost = selectedProvince.dataset.shippingCost
tax = selectedProvince.dataset.tax
dealLimiter = selectedProvince.dataset.dealLimiter,
dealCoupon = selectedProvince.dataset.dealCoupon;
});
if (selectedProvince.value === saskatchewan) {
shippingCost = "0"
tax = order_total * 0.05
dealLimiter = "30"
dealCoupon = "5"
document.getElementById("cart-subtotal-price").value = order_total + shippingCost + tax - dealCoupon
}
if (selectedProvince.value === alberta) {
shippingCost = "2"
tax = order_total * 0.05
dealLimiter = "0"
dealCoupon = "0"
document.getElementById("cart-subtotal-price").value = order_total + shippingCost + tax - dealCoupon
} if (selectedProvince.value === manitoba) {
shippingCost = "2"
tax = order_total * 0.06
dealLimiter = "0"
dealCoupon = "0"
document.getElementById("cart-subtotal-price").value = order_total + shippingCost + tax - dealCoupon
}
</script>
</body>
</html
I expect if Saskatchewan is chosen it should include a 5% tax onto the sales price and if they spend $30 they get $5 taken off. If Alberta is selected they would get $2 shipping added and 5% tax added onto the sales price. If Manitoba is selected they would get $2 shipping added and 6% tax added onto the sales price.

I've gone and spent the time to clean up your code and the errors within in. Please compare my snippet below with your code to understand the issues.
You will be able to copy paste it in replacing the old code and it will work as I worked off of what you had initially.
function updateCartTotal() {
const cartItemContainer = document.getElementsByClassName('cart-items')[0],
cartRows = cartItemContainer.getElementsByClassName('cart-row');
let sub_total = 0;
for (let i = 0; i < cartRows.length; i++) {
const cartRow = cartRows[i],
priceElement = cartRow.getElementsByClassName('cart-price')[0],
quantityElement = cartRow.getElementsByClassName('cart-quantity-input')[0],
price = parseFloat(priceElement.innerText.replace('$', '')),
quantity = quantityElement.value;
sub_total += (price * quantity);
}
const order_total = Math.round(calculateTotal(sub_total) * 100) / 100;
document.getElementsByClassName('cart-total-price')[0].innerText = '$' + order_total;
}
function calculateTotal(sub_total){
const select = document.getElementById("province"),
selectedProvince = select.options[select.selectedIndex],
shippingCost = selectedProvince.dataset.shippingCost,
tax = selectedProvince.dataset.tax,
dealLimiter = selectedProvince.dataset.dealLimiter,
dealCoupon = selectedProvince.dataset.dealCoupon,
appliedCoupon = parseFloat(sub_total) > parseFloat(dealLimiter) ? parseFloat(dealCoupon) : 0,
pretotal = ((sub_total + parseFloat(shippingCost) - appliedCoupon)),
total = pretotal + (pretotal * parseFloat(tax));
return total;
}
document.getElementById("province").addEventListener("change", calculateTotal());

Related

Javascript design pattern publish-subscribe

I'm learning and practicing Javascript publish-subscribe design pattern.
Here is the code: https://codesandbox.io/s/javascript-forked-5vb602?file=/index.js.
What my issue is, when I want to calculate the most expensive unit, when the previous most expensive unit change to 0, I don't know how to find a new highest unit value.
On the most-expensive-minus, I can only find the corresponding unit price, but not others. So how can I find other values?
This is the whole code:
HTML:
<div id="root">
<div id="box">
<ul>
<li>
<input type="button" value="-" />
<span class="num">0</span>
<input type="button" value="+" />
<span>single price:</span>
$<span class="unit">15;</span>
<span class="label">total:</span>
$<span class="subtotal">0</span>
</li>
<li>
<input type="button" value="-" />
<span class="num">0</span>
<input type="button" value="+" />
<span>single price:</span>
$<span class="unit">10;</span>
<span class="label">total:</span>
$<span class="subtotal">0</span>
</li>
<li>
<input type="button" value="-" />
<span class="num">0</span>
<input type="button" value="+" />
<span>single price:</span>
$<span class="unit">5;</span>
<span class="label">total:</span>
$<span class="subtotal">0</span>
</li>
<li>
<input type="button" value="-" />
<span class="num">0</span>
<input type="button" value="+" />
<span>single price:</span>
$<span class="unit">2;</span>
<span class="label">total:</span>
$<span class="subtotal">0</span>
</li>
<li>
<input type="button" value="-" />
<span class="num">0</span>
<input type="button" value="+" />
<span>single price:</span>
$<span class="unit">1;</span>
<span class="label">total:</span>
$<span class="subtotal">0</span>
</li>
</ul>
<div class="total-box">
total purchase
<span id="goods-num">0</span>
; total cost $
<span id="total-price">0</span>
; most expensieve single one is $<span id="unit-price">0</span>
</div>
</div>
</div>
Javascript:
const Event = {
userList: {},
subscribe(key, fn) {
if (!this.userList[key]) {
this.userList[key] = [];
}
this.userList[key].push(fn);
},
publish() {
const key = Array.prototype.shift.apply(arguments);
const fns = this.userList[key];
if (!fns || fns.length === 0) {
return false;
}
for (let i = 0, len = fns.length; i < len; i++) {
fns[i].apply(this, arguments);
}
}
};
(function () {
const aBtnMinus = document.querySelectorAll("#box li>input:first-child");
const aBtnPlus = document.querySelectorAll("#box li>input:nth-of-type(2)");
const oTotalPrice = document.querySelector("#total-price");
const oUnitPrice = document.querySelector("#unit-price");
let curUnitPrice = 0;
for (let i = 0, len = aBtnMinus.length; i < len; i++) {
aBtnMinus[i].index = aBtnPlus[i].index = i;
aBtnMinus[i].onclick = function () {
this.parentNode.children[1].innerHTML > 0 &&
Event.publish("total-goods-num-minus");
--this.parentNode.children[1].innerHTML < 0 &&
(this.parentNode.children[1].innerHTML = 0);
curUnitPrice = this.parentNode.children[4].innerHTML;
Event.publish(
`minus-num${this.index}`,
parseInt(curUnitPrice),
parseInt(this.parentNode.children[1].innerHTML)
);
Event.publish(
`total-minus`,
parseInt(curUnitPrice),
parseInt(this.parentNode.children[1].innerHTML),
parseInt(oTotalPrice.innerHTML)
);
Event.publish(
`most-expensive-minus`,
parseInt(curUnitPrice),
parseInt(this.parentNode.children[1].innerHTML),
parseInt(oUnitPrice.innerHTML)
);
};
aBtnPlus[i].onclick = function () {
this.parentNode.children[1].innerHTML >= 0 &&
Event.publish("total-goods-num-plus");
this.parentNode.children[1].innerHTML++;
curUnitPrice = this.parentNode.children[4].innerHTML;
Event.publish(
`plus-num${this.index}`,
parseInt(curUnitPrice),
parseInt(this.parentNode.children[1].innerHTML)
);
Event.publish(
`total-plus`,
parseInt(curUnitPrice),
parseInt(this.parentNode.children[1].innerHTML),
parseInt(oTotalPrice.innerHTML)
);
Event.publish(
`most-expensive-plus`,
parseInt(curUnitPrice),
parseInt(oUnitPrice.innerHTML)
);
};
}
})();
(function () {
const aSubtotal = document.querySelectorAll("#box .subtotal");
const oGoodsNum = document.querySelector("#goods-num");
const oTotalPrice = document.querySelector("#total-price");
const oUnitPrice = document.querySelector("#unit-price");
Event.subscribe("total-goods-num-plus", function () {
++oGoodsNum.innerHTML;
});
Event.subscribe("total-goods-num-minus", function () {
--oGoodsNum.innerHTML;
});
Event.subscribe(`total-plus`, function (unitPrice, num, originalPrice) {
oTotalPrice.innerHTML =
originalPrice - unitPrice * (num - 1) + unitPrice * num;
});
Event.subscribe(`total-minus`, function (unitPrice, num, originalPrice) {
if (num > 0)
oTotalPrice.innerHTML =
originalPrice + unitPrice * (num - 1) - unitPrice * num;
});
Event.subscribe(`most-expensive-plus`, function (
unitPrice,
originalMostExpensive
) {
oUnitPrice.innerHTML =
originalMostExpensive < unitPrice ? unitPrice : originalMostExpensive;
});
Event.subscribe(`most-expensive-minus`, function (
unitPrice,
num,
originalMostExpensive
) {
if (num > 0) {
oUnitPrice.innerHTML =
originalMostExpensive < unitPrice ? unitPrice : originalMostExpensive;
} else {
oUnitPrice.innerHTML = "xx"; //how to find the new highest price?;
}
});
for (let i = 0, len = aSubtotal.length; i < len; i++) {
Event.subscribe(`minus-num${i}`, function (unitPrice, num) {
aSubtotal[i].innerHTML = unitPrice * num;
});
Event.subscribe(`plus-num${i}`, function (unitPrice, num) {
aSubtotal[i].innerHTML = unitPrice * num;
});
}
})();

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>

problem with loop in google web script app

Good night, how are you?
I created a form, that before the information is inserted in the spreadsheets, the data goes to an HTML table, where you can delete or edit it before sending the data, so far so good,
the problem that I tried to create a loop to go clicking several times until all the data in the table ends, the problem that when I run the loop there is an error that all the data cannot go to the spreadsheet.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body id="pagina">
<br>
<div class= "container">
<div class="row">
<div class="input-field col s12 l4">
<input id="saiDesc" type="text" class="autocomplete" class="validate" required>
<!--<label for="saiDesc" class="active">DESCRIÇÃO DO PRODUTO</label>-->
<label>PRODUTO</label><label class="validation-error hide" id="fullNameValidationError">This field is required.</label>
</div>
<div class="input-field col s6 l1">
<input id="saiCod" type="text" class="validate" required>
<label for="saiCod">CÓDIGO</label>
</div>
<div class="input-field col s6 l1">
<input id="saiQtd" type="text" class="validate" required>
<label for="saiQtd">QUANTIDADE</label>
</div>
<div class="input-field col s6 l1">
<input id="saiVlr" type="text" class="validate" required>
<label for="saiVlr">VALOR</label>
</div>
<div class="input-field col s6 l1">
<input id="saiTotal" type="text" class="validate" required>
<label for="saiTotal">VALOR TOTAL</label>
</div>
<div class="input-field col s12 l4">
<input id="saiObs" type="text" class="validate" required>
<label for="saiObs">OBSERVAÇÃO</label>
</div>
</div> <!-- Fecha Row -->
<div class="row">
<div class="input-field col s6 l1">
<input disabled id="saiTotalizador" type="text">
<label for="saiTotalizador">TOTAL</label>
</div>
<div class="center-align">
<button id="teste" onclick="onFormSubmit(); sum();" class="left waves-effect waves-light btn red darken-2"><i class="material-icons left">add</i>ADD</button>
<button id="teste" onclick="preencher();" class="center waves-effect waves-light btn blue darken-2"><i class="material-icons left">add</i>preencher</button>
<button id="registrar2" class="right waves-effect waves-light btn blue-grey darken-2"><i class="material-icons left">send</i>REGISTER ALL</button>
</div> <!-- Fecha Row -->
</div>
<hr>
<!--<div class="form-action-buttons">
<input type="submit" onclick="onFormSubmit();"value="Enviar">
</div>-->
<td>
<table class="list" id="employeeList">
<thead>
<tr>
<th>PRODUTO</th>
<th>CÓD INT.</th>
<th>QUANT.</th>
<th>VALOR<br/>UNIT.</th>
<th>VALOR<br/>TOTAL</th>
<th>OBS.</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> <!-- Fecha Conatainer -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
var selectedRow = null
function onFormSubmit() {
if (validate()) {
var formData = readFormData();
if (selectedRow == null)
insertNewRecord(formData);
else
updateRecord(formData);
resetForm();
}
}
function readFormData() {
var formData = {};
formData["saiDesc"] = document.getElementById("saiDesc").value;
formData["saiCod"] = document.getElementById("saiCod").value;
formData["saiQtd"] = document.getElementById("saiQtd").value;
formData["saiVlr"] = document.getElementById("saiVlr").value;
formData["saiTotal"] = document.getElementById("saiTotal").value;
formData["saiObs"] = document.getElementById("saiObs").value;
return formData;
}
function insertNewRecord(data) {
var table = document.getElementById("employeeList").getElementsByTagName('tbody')[0];
var newRow = table.insertRow(table.length);
cell1 = newRow.insertCell(0);
cell1.innerHTML = data.saiDesc;
cell2 = newRow.insertCell(1);
cell2.innerHTML = data.saiCod;
cell3 = newRow.insertCell(2);
cell3.innerHTML = data.saiQtd;
cell4 = newRow.insertCell(3);
cell4.innerHTML = data.saiVlr;
cell5 = newRow.insertCell(4);
cell5.innerHTML = data.saiTotal;
cell6 = newRow.insertCell(5);
cell6.innerHTML = data.saiObs;
cell6 = newRow.insertCell(6);
cell6.innerHTML = `<a onClick="onEdit(this)" id="testeEdit" class="btn-floating blue"><i class="material-icons left">edit</i></a>
<a onClick="onDelete(this)" id="testedelete" class="btn-floating red" ><i class="material-icons left">delete</i></a>`;
}
function resetForm() {
document.getElementById("saiDesc").value = "";
document.getElementById("saiCod").value = "";
document.getElementById("saiQtd").value = "";
document.getElementById("saiVlr").value = "";
document.getElementById("saiTotal").value = "";
document.getElementById("saiObs").value = "";
selectedRow = null;
}
function onEdit(td) {
selectedRow = td.parentElement.parentElement;
document.getElementById("saiDesc").value = selectedRow.cells[0].innerHTML;
document.getElementById("saiCod").value = selectedRow.cells[1].innerHTML;
document.getElementById("saiQtd").value = selectedRow.cells[2].innerHTML;
document.getElementById("saiVlr").value = selectedRow.cells[3].innerHTML;
document.getElementById("saiTotal").value = selectedRow.cells[4].innerHTML;
document.getElementById("saiObs").value = selectedRow.cells[5].innerHTML;
M.updateTextFields();
}
function updateRecord(formData) {
selectedRow.cells[0].innerHTML = formData.saiDesc;
selectedRow.cells[1].innerHTML = formData.saiCod;
selectedRow.cells[2].innerHTML = formData.saiQtd;
selectedRow.cells[3].innerHTML = formData.saiVlr;
selectedRow.cells[4].innerHTML = formData.saiTotal;
selectedRow.cells[5].innerHTML = formData.saiObs;
}
function onDelete(td) {
// if (confirm('Are you sure to delete this record ?')) {
row = td.parentElement.parentElement;
document.getElementById("employeeList").deleteRow(row.rowIndex);
resetForm();
//}
}
function validate() {
isValid = true;
if (document.getElementById("saiDesc").value == "") {
isValid = false;
document.getElementById("fullNameValidationError").classList.remove("hide");
} else {
isValid = true;
if (!document.getElementById("fullNameValidationError").classList.contains("hide"))
document.getElementById("fullNameValidationError").classList.add("hide");
}
return isValid;
}
function sum() {
var table = document.getElementById("employeeList");
var sumVal = 0;
for(var i = 1; i < table.rows.length; i++)
sumVal = sumVal + parseFloat(table.rows[i].cells[4].innerHTML.replace(",", "."));
document.getElementById("saiTotalizador").value = sumVal;
M.updateTextFields();
}
function preencher(){
document.getElementById("saiDesc").value = Math.floor((Math.random() * 10) + 1);
document.getElementById("saiCod").value = Math.floor((Math.random() * 10) + 1);
document.getElementById("saiQtd").value = Math.floor((Math.random() * 10) + 1);
document.getElementById("saiVlr").value = Math.floor((Math.random() * 10) + 1);
document.getElementById("saiTotal").value = Math.floor((Math.random() * 10) + 1);
document.getElementById("saiObs").value = Math.floor((Math.random() * 10) + 1);
M.updateTextFields();
}
document.getElementById("registrar2").addEventListener("click",registrarTudo2);
function registrarTudo2(){
var linhas = employeeList.querySelectorAll("tr").length-1;
for (var i = 0; i < linhas; i ++){
document.getElementById("testeEdit").click();
var userInfo = {};
userInfo.saiDesc = document.getElementById("saiDesc").value;
userInfo.saiCod = document.getElementById("saiCod").value;
userInfo.saiQtd = document.getElementById("saiQtd").value;
userInfo.saiVlr = document.getElementById("saiVlr").value;
userInfo.saiTotal = document.getElementById("saiTotal").value;
userInfo.saiObs = document.getElementById("saiObs").value;
google.script.run.registrar(userInfo);
document.getElementById("testedelete").click();
};
};
</script>
</body>
</html>
Gas:
function registrar(userInfo){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1XVICy3RPRRUPtyXtgSi9Ab7iaOOODM6zkJ3Fq4T-h_M/edit#gid=0");
var ws = ss.getSheetByName("Página1");
ws.appendRow([userInfo.saiDesc,
userInfo.saiCod,
userInfo.saiQtd,
userInfo.saiVlr,
userInfo.saiTotal,
userInfo.saiObs
]);
}
note: if I take the loop and click 2x, 3x, 15x, the register button runs the script right.
just with the loop it gives the error.
How about this modification?
Modification points:
I think that the reason of your issue is that google.script.run is run with the asynchronous process. But in your case, the method of appendRow is used in the for loop at Google Apps side. In this case, the process cost will be high. So in this answer, I would like to propose the following flow.
Retrieve all values of userInfo and put them to an array.
Send the array to Google Apps Script side using google.script.run.
At Google Apps Script side, convert the array for putting to Spreadsheet and put the values.
When above points are reflected to your script, it becomes as follows.
Modified script:
HTML&Javascript side:
Please modify registrarTudo2() as follows.
function registrarTudo2(){
var values = []; // Added
var linhas = employeeList.querySelectorAll("tr").length-1;
for (var i = 0; i < linhas; i ++){
document.getElementById("testeEdit").click();
var userInfo = {};
userInfo.saiDesc = document.getElementById("saiDesc").value;
userInfo.saiCod = document.getElementById("saiCod").value;
userInfo.saiQtd = document.getElementById("saiQtd").value;
userInfo.saiVlr = document.getElementById("saiVlr").value;
userInfo.saiTotal = document.getElementById("saiTotal").value;
userInfo.saiObs = document.getElementById("saiObs").value;
values.push(userInfo); // Added
document.getElementById("testedelete").click();
}
google.script.run.registrar(values); // Added
}
Google Apps Script side:
Please modify registrar() as follows.
function registrar(values){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/###/edit#gid=0");
var ws = ss.getSheetByName("Página1");
var v = values.map(userInfo => [userInfo.saiDesc,userInfo.saiCod,userInfo.saiQtd,userInfo.saiVlr,userInfo.saiTotal,userInfo.saiObs]); // Added
ws.getRange(ws.getLastRow() + 1, 1, v.length, v[0].length).setValues(v); // Added
}
Please set the URL of your Spreadsheet to SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/###/edit#gid=0").
References:
Class google.script.run
setValues(values)

Shopping Cart with JavaScript

I'm building a shopping cart with Vanilla JavaScript and i'm trying with Console.Log to show price of product "$19.99" when i click button to remove the product, but it's not showing nothing in Console.Log and i think problem is with html but i cannot find it, any idea?
<div class="click-cart">
<div class="cart-row">
<span class="cart-item cart-header cart-column">ITEM</span>
<span class="cart-price cart-header cart-column">PRICE</span>
<span class="cart-quantity cart-header cart-column">QUANTITY</span></div>
<div class="olp">
<div class="lakn">
<img class="shop-item-cart" src="https://cdn.thewirecutter.com/wp-content/uploads/2018/04/canon-dslrs-march-2018-2x1-lowres3496.jpg">
<span class="shop-title">Album 1</span>
<span class="shop-price">$19.99</span>
<input class="quantity-input" type="number" value="1">
<button class="delete-cart">X</button>
</div></div>
<div class="clear-checkout">
<button class="checkout">Checkout</button>
<button class="clear-cart">Clear Cart</button></div>
<div class="cart-items">
</div>
<div class="cart-total">
<strong class="cart-total-title">Total</strong>
<span class="cart-total-price">$10.79</span>
</div>
for (let i = 0; i < removeCartItemButtons.length; i++) {
let button = removeCartItemButtons[i]
button.addEventListener('click', function (event) {
let buttonCliked = event.target
buttonCliked.parentElement.parentElement.remove()
updateCartTotal ()
})
}
function updateCartTotal () {
let cartItemContainer = document.querySelector('.click-cart');
let cartRows = cartItemContainer.querySelector('.cart-row');
for (let i = 0; i < cartRows.length; i++) {
let cartRow = cartRows[i]
let priceElement = cartRow.querySelector('.shop-price');
let quantityElement = cartRow.querySelector('.quantity-input');
let price = priceElement.innerText
console.log(price)
}
}```
<div class="cart-row">
<span class="cart-item cart-header cart-column">ITEM</span>
<span class="cart-price cart-header cart-column">PRICE</span>
<span class="cart-quantity cart-header cart-column">QUANTITY</span>
</div>
The shop-price element is not in the cart-row div.
Furthermore, your for loop would not run because cartRows is not an array, instead it is a single HTMLElement with a length of undefined, use cartItemContainer.querySelectorAll('.cart-row') to get an interable NodeList instead.
Additionally, since you delete the element before you use the updateCartTotal function it is necessary to have a price variable preset to 0.
function updateCartTotal () {
let cartItemContainer = document.querySelector('.click-cart');
let cartRows = cartItemContainer.querySelectorAll('.cart-row');
let price = 0;
for (let i = 0; i < cartRows.length; i++) {
let cartRow = cartRows[i]
let priceElement = cartRow.querySelector('.shop-price');
let quantityElement = cartRow.querySelector('.quantity-input');
if (priceElement) {
price += Number(priceElement.innerText.replace('$',''));
}
console.log(price);
}
}

Why my button is not working in the input form?

The expected behaviour of the code above is when I click the "Add" button the issue is created and is shown beneath the button. The problem is, nothing happens instead. I've been trying to search the web to find an answer but with no luck. Any idea what's wrong?
Here are my index.html and JavaScript:
document.getElementById('issueInputForm').addEventListener('submit', saveIssue);
function saveIssue(e) {
var issueDesc = document.getElementById('issueDescInput').value;
var issueSeverity = document.getElementById('issueSeverityInput').value;
var issueAssignedTo = document.getElementById('issueAssigntedToInput').value;
var issueID = chance.guid();
var issueStatus = 'Open';
var issue = {
id: issueID,
description: issueDesc,
severity: issueSeverity,
assignedTo: issueAssignedTo,
status: issueStatus
};
if (localStorage.getItem('issues') === null) {
//var issues = [];
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
} else {
var issues = JSON.parse(localStorage.getItem('issues'));
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
}
document.getElementById('issueInputForm').reset();
fetchIssue();
e.preventDefault();
}
function setStatusClosed(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++)
if (issues[i].id === id)
issues[i].status = 'Closed';
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function deleteIssue(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++)
if (issues[i].id === id)
issues.splice(i, 1);
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function fetchIssue() {
var issues = JSON.parse(localStorage.getItem('issues'));
var issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (var i = 0; i < issues.length; i++) {
var id = issues[i].id;
var desc = issues[i].description;
var severity = issues[i].severity;
var assignedTo = issues[i].assignedTo;
var status = issues[i].status;
issuesList.innerHTML += '<div class="well">' +
'<h6> Issue ID: ' + id + '</h6>' +
'<p><span class="label label-info">' + status + '</span></p>' +
'<h3>' + desc + '</h3>' +
'<p><span class="glyphicon glyphicon-time"></span>' + severity + '</p>' +
'<p><span class="glyphicon glyphicon-user"></span>' + assignedTo + '</p>' +
'Close' +
'Delete'+
'</div>';
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Issue Tracker</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body onload="fetchIssue()">
<div class="container">
<h1>JS IssueTracker</h1>
</div class="jumbotron">
<h3>Add New Issue:</h3>
<form id="issueInputForm" >
<div class="form-group">
<label for="issueDescInput">Description</label>
<input type="text" class="form-control" id="issueDescInput" placeholder="Describe the issue...">
</div>
<div class="form-group">
<label for="issueSeverityInput">Severity</label>
<select id="issueSeverityInput" class="form-control">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedToInput">Assigned to</label>
<input type="text" class="form-control" id="issueAssignedToInput" placeholder="Enter responsible">
</div>
<button type="button" class="btn btn-primary">Add</button>
</form>
<div class="col-lg-12">
<div id="issuesList"></div>
</div>
<div class="footer">
<p>© Ida Djurhuus</p>
</div>
<script src="http://chancejs.com/chance.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>
As #epascarello already mentioned
type="button" does not submit forms
So change the type to submit
<button type="submit" class="btn btn-primary">Add</button>
From MDN
button: The button has no default behavior. It can have client-side scripts associated with the element's events, which are triggered when the events occur.
submit: The button submits the form data to the server. This is the default if the attribute is not specified, or if the attribute is dynamically changed to an empty or invalid value.
in your code 2 problem
1) change type="button" to type="submit"
2) var issueAssignedTo = document.getElementById('issueAssigntedToInput').value;
chaneg this line in id
var issueAssignedTo = document.getElementById('issueAssignedToInput').value;
document.getElementById('issueInputForm').addEventListener('submit', saveIssue);
function saveIssue(e) {
debugger;
var issueDesc = document.getElementById('issueDescInput').value;
var issueSeverity = document.getElementById('issueSeverityInput').value;
var issueAssignedTo = document.getElementById('issueAssignedToInput').value;
var issueID = chance.guid();
var issueStatus = 'Open';
var issue = {
id: issueID,
description: issueDesc,
severity: issueSeverity,
assignedTo: issueAssignedTo,
status: issueStatus
};
if (localStorage.getItem('issues') === null) {
//var issues = [];
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
} else {
var issues = JSON.parse(localStorage.getItem('issues'));
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
}
document.getElementById('issueInputForm').reset();
fetchIssue();
e.preventDefault();
}
function setStatusClosed(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++) {
if (issues[i].id === id) {
issues[i].status = 'Closed';
}
}
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function deleteIssue(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++) {
if (issues[i].id === id) {
issues.splice(i, 1);
}
}
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function fetchIssue() {
var issues = JSON.parse(localStorage.getItem('issues'));
var issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (var i = 0; i < issues.length; i++) {
var id = issues[i].id;
var desc = issues[i].description;
var severity = issues[i].severity;
var assignedTo = issues[i].assignedTo;
var status = issues[i].status;
issuesList.innerHTML += '<div class="well">' +
'<h6> Issue ID: ' + id + '</h6>' +
'<p><span class="label label-info">' + status + '</span></p>' +
'<h3>' + desc + '</h3>' +
'<p><span class="glyphicon glyphicon-time"></span>' + severity + '</p>' +
'<p><span class="glyphicon glyphicon-user"></span>' + assignedTo + '</p>' +
'Close' +
'Delete'+
'</div>';
}
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<div class="container">
<h1>JS IssueTracker</h1>
</div class="jumbotron">
<h3>Add New Issue:</h3>
<form id="issueInputForm" >
<div class="form-group">
<label for="issueDescInput">Description</label>
<input type="text" class="form-control" id="issueDescInput" placeholder="Describe the issue...">
</div>
<div class="form-group">
<label for="issueSeverityInput">Severity</label>
<select id="issueSeverityInput" class="form-control">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedToInput">Assigned to</label>
<input type="text" class="form-control" id="issueAssignedToInput" placeholder="Enter responsible">
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
<div class="col-lg-12">
<div id="issuesList">
</div>
</div>
<div class="footer">
<p>© Ida Djurhuus</p>
</div>
<script src="http://chancejs.com/chance.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
Have made few changes to your code:
Since element with type="button" cannot be associated with submit event, have changed the type as submit.
Added null check in fetchIssue function so that the code wont break when there are no issues.
Corrected a typo in the saveIssue function - document.getElementById('issueAssigntedToInput') to document.getElementById('issueAssignedToInput')
Declared variable "issues" in saveIssue function when the localStorage.getItem('issues') is null.
document.getElementById('issueInputForm').addEventListener('submit', saveIssue);
function saveIssue(e) {
var issueDesc = document.getElementById('issueDescInput').value;
var issueSeverity = document.getElementById('issueSeverityInput').value;
var issueAssignedTo = document.getElementById('issueAssignedToInput').value;
var issueID = chance.guid();
var issueStatus = 'Open';
var issue = {
id: issueID,
description: issueDesc,
severity: issueSeverity,
assignedTo: issueAssignedTo,
status: issueStatus
};
var issues = [];
if (localStorage.getItem('issues') !== null) {
issues = JSON.parse(localStorage.getItem('issues'));
}
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
document.getElementById('issueInputForm').reset();
fetchIssue();
e.preventDefault();
}
function setStatusClosed(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++) {
if (issues[i].id === id) {
issues[i].status = 'Closed';
}
}
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function deleteIssue(id) {
var issues = JSON.parse(localStorage.getItem('issues'));
for (var i = 0; i < issues.length; i++) {
if (issues[i].id === id) {
issues.splice(i, 1);
}
}
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssue();
}
function fetchIssue() {
var issues = JSON.parse(localStorage.getItem('issues'));
if(typeof issues !== 'undefined' && issues !== null) {
var issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (var i = 0; i < issues.length; i++) {
var id = issues[i].id;
var desc = issues[i].description;
var severity = issues[i].severity;
var assignedTo = issues[i].assignedTo;
var status = issues[i].status;
issuesList.innerHTML += '<div class="well">' +
'<h6> Issue ID: ' + id + '</h6>' +
'<p><span class="label label-info">' + status + '</span></p>' +
'<h3>' + desc + '</h3>' +
'<p><span class="glyphicon glyphicon-time"></span>' + severity + '</p>' +
'<p><span class="glyphicon glyphicon-user"></span>' + assignedTo + '</p>' +
'Close' +
'Delete'+
'</div>';
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Issue Tracker</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body onload="fetchIssue()">
<div class="container">
<h1>JS IssueTracker</h1>
</div>
<h3>Add New Issue:</h3>
<form id="issueInputForm" >
<div class="form-group">
<label for="issueDescInput">Description</label>
<input type="text" class="form-control" id="issueDescInput" placeholder="Describe the issue...">
</div>
<div class="form-group">
<label for="issueSeverityInput">Severity</label>
<select id="issueSeverityInput" class="form-control">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedToInput">Assigned to</label>
<input type="text" class="form-control" id="issueAssignedToInput" placeholder="Enter responsible">
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
<div class="col-lg-12">
<div id="issuesList">
</div>
</div>
<div class="footer">
<p>© Ida Djurhuus</p>
</div>
<script src="http://chancejs.com/chance.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>

Categories