Select only targeted item and remove it - clear innerHtml - javascript

I am currently building and invoice creator app as to practice javascript.
My goal is that when the user presses the "remove" button, only the clicked item will be removed from the list.
const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const renderItem = document.querySelector('.render');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');
let totalAmount = 0;
theForm.addEventListener('submit', function(e) {
e.preventDefault();
totalAmount += parseInt(selectOption.value);
renderItem.innerHTML += `
<div class="render-item">
<div class="left-side">
<h2>${taskInput.value}</h2>
<button class='remove'>Remove</button>
</div>
<h2><span>$</span>${selectOption.value}</h2>
</div>
`;
totalSum.textContent = `$${totalAmount}`;
taskInput.value = '';
selectOption.value = '10';
const removeItem = document.querySelectorAll('.render-item');
removeItem.forEach((item) => {
item.addEventListener('click', function() {
renderItem.innerHTML = '';
totalAmount = 0;
totalSum.textContent = '';
});
});
});
<div class="outer-container">
<header>
<h1>Invoice creator</h1>
<p>Thanks for choosing RazCorp, LLC!</p>
</header>
<main class="inner-container">
<section class="form-enter">
<form id="the-form">
<input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
<div class="amount-container">
<label for="amount">$</label>
<select name="amount" id="amount">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select>
</div>
<button id="submit-btn" class="submit" type="submit">+</button>
</form>
</section>
<section class="display">
<div class="task-total">
<h3>TASK</h3>
<h3>TOTAL</h3>
</div>
<div class="render"></div>
</section>
<section class="final-amount">
<div class="final-left">
<h3>NOTES</h3>
<p>We accept cash, credit card, or PayPal</p>
</div>
<div class="final-right">
<h3>TOTAL AMOUNT</h3>
<h1 id="total-sum"></h1>
</div>
</section>
<button id="send-invoice" class="send-invoice">
<span><i class="fa-solid fa-envelope"></i></span>Send invoice
</button>
</main>
</div>
First I am creating the Html through javascript and then I would like to remove it.
Right now when I press remove, every new created redenerItem is deleted and not just the one being clicked.
Any help appreciated :)

Because you have a single element that you're adding all of the entries to, when you press the remove button and it clears that single element, it clears all of the entries. What you probably want is a system that stores an array of all the items in the list, then selectively removing them. You might be able to use this:
const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');
const renderItems = document.querySelector('.render');
const listItems = [];
let totalAmount = 0;
theForm.addEventListener('submit', function (e) {
e.preventDefault();
totalAmount += parseInt(selectOption.value);
//The Array.push method returns the new length of the array that we can use to get the item position
let itemPos = listItems.push(document.createElement('div')) - 1;
listItems[itemPos].innerHTML = `
<div class="left-side">
<h2>${taskInput.value}</h2>
<button class='remove' onclick='removeItem(${itemPos}, ${selectOption.value})'>Remove</button>
</div>
<h2><span>$</span>${selectOption.value}</h2>
`;
renderItems.appendChild(listItems[itemPos]);
totalSum.textContent = `$${totalAmount}`;
taskInput.value = '';
selectOption.value = '10';
});
//Move the remove item functionality to a new function
function removeItem(index, value) {
listItems[index].remove(); //Remove the element from the DOM
listItems.splice(index, 1); //Remove the element from the array
totalAmount -= value;
totalSum.textContent = `$${totalAmount}`;
}
<div class="outer-container">
<header>
<h1>Invoice creator</h1>
<p>Thanks for choosing RazCorp, LLC!</p>
</header>
<main class="inner-container">
<section class="form-enter">
<form id="the-form">
<input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
<div class="amount-container">
<label for="amount">$</label>
<select name="amount" id="amount">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select>
</div>
<button id="submit-btn" class="submit" type="submit">+</button>
</form>
</section>
<section class="display">
<div class="task-total">
<h3>TASK</h3>
<h3>TOTAL</h3>
</div>
<div class="render"></div>
</section>
<section class="final-amount">
<div class="final-left">
<h3>NOTES</h3>
<p>We accept cash, credit card, or PayPal</p>
</div>
<div class="final-right">
<h3>TOTAL AMOUNT</h3>
<h1 id="total-sum"></h1>
</div>
</section>
<button id="send-invoice" class="send-invoice">
<span><i class="fa-solid fa-envelope"></i></span>Send invoice
</button>
</main>
</div>

const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const renderItem = document.querySelector('.render');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');
let totalAmount = 0;
theForm.addEventListener('submit', function(e) {
e.preventDefault();
totalAmount += parseInt(selectOption.value);
renderItem.innerHTML += `
<div class="render-item">
<div class="left-side">
<h2>${taskInput.value}</h2>
<button class='remove'>Remove</button>
</div>
<h2><span>$</span>${selectOption.value}</h2>
</div>
`;
totalSum.textContent = `$${totalAmount}`;
taskInput.value = '';
selectOption.value = '10';
const removeItem = document.querySelectorAll('.render-item');
removeItem.forEach((item) => {
item.addEventListener('click', function() {
this.remove();
/*totalAmount = 0;
totalSum.textContent = '';*/
});
});
});
<div class="outer-container">
<header>
<h1>Invoice creator</h1>
<p>Thanks for choosing RazCorp, LLC!</p>
</header>
<main class="inner-container">
<section class="form-enter">
<form id="the-form">
<input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
<div class="amount-container">
<label for="amount">$</label>
<select name="amount" id="amount">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select>
</div>
<button id="submit-btn" class="submit" type="submit">+</button>
</form>
</section>
<section class="display">
<div class="task-total">
<h3>TASK</h3>
<h3>TOTAL</h3>
</div>
<div class="render"></div>
</section>
<section class="final-amount">
<div class="final-left">
<h3>NOTES</h3>
<p>We accept cash, credit card, or PayPal</p>
</div>
<div class="final-right">
<h3>TOTAL AMOUNT</h3>
<h1 id="total-sum"></h1>
</div>
</section>
<button id="send-invoice" class="send-invoice">
<span><i class="fa-solid fa-envelope"></i></span>Send invoice
</button>
</main>
</div>
your event listener is already on the render-item, so just remove the element clicked.
now you will have the problem to update the amount and the text of 0.
you should add a class for the amount of each render-item, actually the amount is after the span that's it. If you have a class "render-item-amount" it would be easier at each update to modify the total

Related

Name Input from form not being inputted to desired span using .innertext [duplicate]

This question already has answers here:
Why are duplicate ID values not allowed in HTML?
(3 answers)
Closed 3 months ago.
I am making a simple quiz where user inputs their name. Upon submitting their results their name and results are displayed.
I gather the user's name input with.
A link to the repo for full code https://github.com/ambibma/programlanguageselector
When user submits form a function handleSubmit(event is executed)
function handleSubmit(event){
event.preventDefault();
and variables are set
let nameInput = document.getElementById("nameinput").value;
const nameResult = document.getElementById("name");
Then branching is used to determine the result, when a result is reached, it is displayed through:
nameResult.innerText = nameInput;
htmlResult.classList.remove("hidden");
However, in my html:
<p> <span id="name">__</span> , you should learn HTML!</p>
The name is not inputted.
function handleSubmit(event){
event.preventDefault();
let nameInput = document.getElementById("nameinput").value;
const nameResult = document.getElementById("name");
Then branching is used to determine the result, when a result is reached, it is displayed through:
nameResult.innerText = nameInput;
htmlResult.classList.remove("hidden");
However, in my html:
<p> <span id="name">__</span> , you should learn HTML!</p>
The name is not inputted.
The problem is that you use the id to refer to a span DOM-element however there are many spans with the same id, which is wrong. The id has to be unique. A fix would be to put a same class to all these 'span' in the .html and to select the correct name depending on the parent in the .js:
Try the following .html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Program Language Matcher</title>
<link rel="stylesheet" href="css/styles.css" type="text/css">
<script src="js/scripts.js"></script>
</head>
<body>
<div id="quiz-start">
<img src="./img/PLSlogo.png" id="plslogo">
<div class="text-div" id="quiz-start-text">
<h1 id="quiz-start-header">Program Language Matcher</h1>
<h2 id="quiz-start-sub-header">Find your missing technological half</h2>
<p class="match-me">Get Matched Now</p>
<p class="match-button"><button class="btn" id="start-quiz">Start!</button></p>
</div>
<div class="quiz-page1 hidden" id="quiz-page1">
<h3>Enter a name:</h3>
<label for="nameinput"></label>
<input id="nameinput" type="text" name="nameinput">
<h3>Do you like puzzles or websites?</h3>
<form>
<div class="question1-form" id="question1-div">
<label for="question1"></label>
<input id="form-question1" type="text"><br>
</div>
<div class="question2-form" id="question2-div">
<h3>Which do you prefer more?</h3>
<select id="question2">
<option value="fox">fox</option>
<option value="coffee">coffee</option>
<option value="snakes">snakes</option>
</select>
</div>
<div class="question3-form" id="question3-div">
<h3>How much do you like Minecraft?</h3>
<select id="minecraft">
<option value="love">I love Minecraft</option>
<option value="hate">I hate Minecraft</option>
<option value="meh">I never played minecraft</option>
</select>
</div>
<div class="question4-form" id="question4-div">
<h3>Do you like<span class="matrix">The Matrix</span>?</h3>
<select id="question4-select">
<option>Yes</option>
<option>No</option>
</select>
</div>
<div class="question5-form" id="question5-div">
<h3>Cats or Dogs?</h3>
<select id="question5-select">
<option>Woof!</option>
<option>Meow!</option>
</select>
</div>
<div class="question6-form" id="question6-div">
<h3>Do you like Epicodus?</h3>
<select id="question6-select">
<option>Yes</option>
<option>Yes</option>
<option>hmm Yes</option>
</select>
</div>
<p><button class="btn" type="submit">Find my other technological half</button></p>
</form>
</div>
<div class="results" id="quiz-results-page">
<div class="htmlresult hidden" id="result1">
<img src="img/html.jpg" alt="hackerstyle html logo" id="htmlimg">
<p> <span class="name">__</span> , you should learn HTML!</p>
<p><button type="onclick" id="reload">Make another Quiz!</button></p>
</div>
<div class="javaresult hidden" id="result2">
<img src="img/java.png" alt="old school java logo" id="javaimg">
<p> <span class="name">__</span> , you should learn javaScript!</p>
<p><button type="onclick" id="reload">Make another Quiz!</button></p>
</div>
<div class="pythonresult hidden" id="result3">
<img src="img/python.jpg" alt="a picture of a python" id="pythonimg">
<p> <span class="name">__</span> , you should learn Python! *hsss*</p>
<p><button type="onclick" id="reload">Make another Quiz!</button></p>
</div>
<div class="csharpresult hidden" id="result4">
<img src="img/csharp.png" alt="csharp logo" id="csharpimg">
<p> <span class="name"></span> you should learn C#!</p>
<p><button type="onclick" id="reload">Make another Quiz!</button></p>
</div>
<div class="warningresult hidden" id="resultwarning">
<h3><span class="warning">You did not put valid inputs!</span></h3>
<p><button type="onclick" id="reload">Try Again</button></p>
</div>
</div>
</body>
</html>
And the following .js:
window.addEventListener("load", function () {
const startQuizBtn = document.getElementById("start-quiz");
let quizStartText = document.getElementById("quiz-start-text");
let quizPage1Form = document.getElementById("quiz-page1");
let quizRestart = document.getElementById("quiz-results-page");
let plsLogo = document.getElementById("plslogo");
function reloadQuiz() {
window.location.reload();
}
function hideQuiz() {
quizStartText.setAttribute("class", "hidden");
quizPage1Form.setAttribute("class", "hidden");
}
function toQuizPage1() {
quizStartText.classList.add("hidden");
plsLogo.classList.add("hidden");
quizPage1Form.classList.remove("hidden");
}
function handleSubmit(event) {
event.preventDefault();
hideQuiz();
const question1Input = document.getElementById("form-question1").value;
const question2Input = document.getElementById("question2").value;
let question3Input = document.getElementById("minecraft").value;
let csharpResult = document.getElementById("result4");
let pythonResult = document.getElementById("result3");
let javascriptResult = document.getElementById("result2");
let htmlResult = document.getElementById("result1");
const resultWarning = document.getElementById("resultwarning");
const nameInput = document.getElementById("nameinput").value;
if (question1Input && question2Input && question3Input) {
if (question1Input === "puzzles" && question2Input === "fox" || question2Input === "snakes" && question3Input === "meh" || question3Input === "hate") {
const nameResult = pythonResult.querySelector('.name')
nameResult.innerText = nameInput
pythonResult.classList.remove("hidden");
} else if (question1Input === "websites" && question2Input === "fox" && question3Input === "meh" || question3Input === "hate") {
const nameResult = htmlResult.querySelector('.name')
nameResult.innerText = nameInput;
htmlResult.classList.remove("hidden");
console.log("ran");
} else if ((question1Input === "puzzles" || "websites") && (question2Input === "coffee") && (question3Input === "love" || question3Input === "meh")) {
const nameResult = javascriptResult.querySelector('.name')
nameResult.innerText = nameInput;
javascriptResult.classList.remove("hidden");
} else {
const nameResult = csharpResult.querySelector('.name')
nameResult.innerText = nameInput;
csharpResult.classList.remove("hidden");
}
} else {
resultWarning.classList.remove("hidden");
}
}
quizRestart.addEventListener("click", reloadQuiz)
quizPage1Form.addEventListener("submit", handleSubmit);
startQuizBtn.addEventListener("click", toQuizPage1);
})

Javascript: modal.style.display = "block" not working

I made a modal that is supposed to pop up when the user clicks the edit button. I hid the modal in CSS with display: none;
for some reason for the JS side I made a function that is linked to the edit button that when button is pressed the modal is changed to display: block;
What I did do was within the function renderList() I used the button onclick="editItem(event, ${i})" for the function editItem(event, i)
/*----Edit budget Entry----*/
function editItem(event, i){
alert("edit button clicked")
let mod = modal.style.display = "block";
console.log(mod)
}
I made a runable code so you can see.
/*----Storage key----*/
const BUDGETLIST_KEY = "user-key-entryList";
/*----Generate ID----*/
const createId = () => `${Math.floor(Math.random() * 10000)}${(new Date().getTime())}`;
/*----Get current Date----*/
function createdDate() {
let currentDate = new Date();
let day = String(currentDate.getDate()).padStart(2, '0');
let month = String(currentDate.getMonth() + 1).padStart(2, '0');
let year = currentDate.getFullYear();
currentDate = month + '/' + day + '/' + year;
return currentDate;
}
/*----Variable Objects----*/
const el = {
list: document.querySelector(".list"),
cashflow: document.querySelector("#cashflow"),
catagory: document.querySelector(".catagory"),
label: document.querySelector(".label"),
number: document.querySelector(".number"),
modal: document.querySelector(".modal"),
};
/*----Array with local Storage----*/
let budgetArray = [];
/*----Budget list Object----*/
function makeNewBudget() {
const data = {
id: createId(),
cashflowNew: el.cashflow.value,
catagoryNew: el.catagory.value,
labelNew: el.label.value,
dateNew: createdDate(),
numberNew: el.number.value,
};
return data;
}
/*----Render Budget List----*/
function renderList() {
el.list.innerHTML = budgetArray.map(function(data, i) {
return `<div class="entry">
<div class="list">
<button onclick="deleteItem(event, ${i})" class="Archive" data-id="${data.id}">
<img src="../resources/Images/archive.png" alt="Archive">
</button>
<button onclick="editItem(event, ${i})" class = "edit" data-id="${data.id}" class = "edit" data-id="${data.id}">
<img src="../resources/Images/edit.png" alt="Edit">
</button>
<div class="input" data-id="${data.id}"></div>
<label class="dateNew">${data.dateNew}</label>
<label class="cashflowNew">${data.cashflowNew}</label>
<label class="catagoryNew">${data.catagoryNew}</label>
<label class="labelNew">${data.labelNew}</label>
<label class="numberNew">${data.numberNew}</label>
</div>
</div>`;
});
}
/*----form validation----*/
let budgetButton = document.querySelector(".budget-button");
let label = document.querySelector(".label");
let num = document.querySelector(".number");
budgetButton.addEventListener("click", () => {
if (!label.value || !num.value) {
alert("please make sure all inputs are filled");
}
budgetArray.push(makeNewBudget())
renderList();
});
/*----Remove from array----*/
function deleteItem(event, i) {
budgetArray.splice(i, 1);
renderList();
}
/*----Close Modal----*/
let close = document.querySelector(".btn-close")
let xBtn = document.querySelector(".btn-secondary")
let modal = document.querySelector(".modal-content")
close.addEventListener('click', () => {
if (close) {
modal.style.display = "none"
}
});
xBtn.addEventListener('click', () => {
if (xBtn) {
modal.style.display = "none"
}
});
/*----Edit budget Entry----*/
function editItem(event, i) {
alert("edit button clicked")
let mod = modal.style.display = "block";
console.log(mod)
}
.modal {
display: block;
margin-top: 15rem;
display: none;
}
<!--Create budget-->
<div class="create-budget">
<form class="budget">
<input class="budget-button" type="button" value="Create your budget">
<select id="cashflow" name="income/expense" class="income/expense">
<option class="options" value="income">Income</option>
<option class="options" value="expense">Expense</option>
</select>
<select name="Catagory" class="catagory" value="Catagory">
<option class="options" value="House Hold">House Hold</option>
<option class="options" value="Car">Car</option>
<option class="options" value="entertainment">Entertainment</option>
<option class="options" value="investments">Investments</option>
<option class="options" value="business">Business</option>
<option class="options" value="savings">Savings</option>
</select>
<input class="label" type="text" placeholder="Example rent">
<input class="number" type="number" placeholder="0,0">
</form>
</div>
<div class="new-budet">
<div class="title">
<h5>Date</h5>
<h5>Income/Expenses</h5>
<h5>Catagory</h5>
<h5>Items</h5>
<h5>Amount</h5>
</div>
</div>
<div class="list"></div>
<div class="budget-update"></div>
<div class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Want to make changes?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form class="budget-update">
<select id="cashflow-update" name="income/expense" class="income/expense">
<option class="options-update" value="income">Income</option>
<option class="options-update" value="expense">Expense</option>
</select>
<select class="catagory-update" name="Catagory" value="Catagory">
<option class="options-update" value="House Hold">House Hold</option>
<option class="options-update" value="Car">Car</option>
<option class="options-update" value="entertainment">Entertainment</option>
<option class="options-update" value="investments">Investments</option>
<option class="options-update" value="business">Business</option>
<option class="options-update" value="savings">Savings</option>
</select>
<input class="label-update" type="text" placeholder="Example rent">
<input class="number-update" type="number" placeholder="0,0">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">
<img src="/resources/Images/Save-icon.png" alt="Save Icon">
</button>
</div>
</div>
</div>
</div>
Thanks to ethry answer it helped solve the problem. I forgot to add a variable for it
let modal= document.querySelector(".modal")
/*----Edit budget Entry----*/
function editItem(event, i){
modal.style.display = "block";
}
In order to use a variable, it needs to be defined. It looks like you accidentally left it undefined.
let modal = document.querySelector(".modal");
/*----Edit budget Entry----*/
function editItem(event, i){
modal.style.display = "block";
}
Or you could replace .querySelector(". with .getElementsByClassName(" and add [0] at the end.
More information about variables:
https://developer.mozilla.org/en-US/docs/Glossary/Variable

PHP code doesn't see input added through js

I have form that collect datas when SAVE button is pressed from three inputs. First two is already loaded on the site, but last appears when DVD-disk is selected in <select>. So PHP code see values from first two inputs, but not from the last one. I added name and id to all of them. Inputs are in the main container that is in form.
Expected output: echo ($DVDdisk) show data
Real output: Undefined index: DVDsize
let selector = document.getElementById("selector");
let main = document.getElementById("input-main-add");
let div = document.createElement('div');
let h2 = document.createElement('H2');
let input = document.createElement('input');
selector.addEventListener("change", (e) => {
if (selector.value == "DVD") {
div.classList.add('input-add-holder');
main.appendChild(div);
h2.textContent = 'Enter size:';
h2.style.display = 'inline-block';
div.appendChild(h2);
input.setAttribute("name", "DVDsize");
input.setAttribute("id", "DVDsize");
div.appendChild(input);
}
});
<form method="POST" action="add.php">
<button class="accept-btn" type="submit">SAVE</button>
<!-- + -->
<button class="decline-btn">CANCEL</button>
<!-- + -->
</div>
</div>
<div class="input-main-add" id="input-main-add">
<!-- + -->
<div class="input-add-holder">
<H2 style="display:inline-block">SKU: </H2>
<input class="something" name="SKU" id="SKU"></input>
</div>
<div class="input-add-holder">
<H2 style="display:inline-block">Name: </H2>
<input class="something" name="name" id="name"></input>
</div>
<div class="input-add-holder">
<H2 style="display:inline-block">Type Switcher: </H2>
<select name="selector" id="selector">
<option value="DVD" id="DVD" name="DVD">DVD-Disk</option>
<option value="book" id="book" name="book">Book</option>
<option value="furniture" id="furniture" name="furniture">Furniture</option>
</select>
</div>
</div>
</form>
PHP code:
<?php
$SKU = $_POST["SKU"];
$name = $_POST["name"];
$DVDsize = $_POST["DVDsize"];
echo ($SKU);
echo ($name);
echo ($DVDsize);
?>
Your JS listen for change event on Type Switcher select box that the selected value must be DVD-Disk but your default value of this select box is DVD-Disk which is already selected.
So, this event will never happens when you just load the page, fill form (without change select box) and submit.
If this event never happens, it means input name DVDSize will not rendered and not send to server. That's why your PHP doesn't see this input.
You have to manually trigger change event for select box once DOM ready.
let selector = document.getElementById("selector");
let main = document.getElementById("input-main-add");
let div = document.createElement('div');
let h2 = document.createElement('H2');
let input = document.createElement('input');
selector.addEventListener("change", (e) => {
if (selector.value == "DVD") {
div.classList.add('input-add-holder');
main.appendChild(div);
h2.textContent = 'Enter size:';
h2.style.display = 'inline-block';
div.appendChild(h2);
input.setAttribute("name", "DVDsize");
input.setAttribute("id", "DVDsize");
div.appendChild(input);
}
});
// manually trigger change event.
let selectTypeSwitcher = document.getElementById('selector');
if (selectTypeSwitcher) {
selectTypeSwitcher.dispatchEvent(new Event('change'));
}
<form method="POST" action="add.php">
<button class="accept-btn" type="submit">SAVE</button>
<!-- + -->
<button class="decline-btn">CANCEL</button>
<!-- + -->
</div>
</div>
<div class="input-main-add" id="input-main-add">
<!-- + -->
<div class="input-add-holder">
<H2 style="display:inline-block">SKU: </H2>
<input class="something" name="SKU" id="SKU"></input>
</div>
<div class="input-add-holder">
<H2 style="display:inline-block">Name: </H2>
<input class="something" name="name" id="name"></input>
</div>
<div class="input-add-holder">
<H2 style="display:inline-block">Type Switcher: </H2>
<select name="selector" id="selector">
<option value="DVD" id="DVD" name="DVD">DVD-Disk</option>
<option value="book" id="book" name="book">Book</option>
<option value="furniture" id="furniture" name="furniture">Furniture</option>
</select>
</div>
</div>
</form>
Run the code above while open network inspector and you will see DVDSize input send to the server.

Tip calculator keeps returning NaN. How to fix errors with Nan?

I'm trying to create a tip calculator, and when I put in all the information it doesn't return the desired amount. Instead it returns Nan. Why does it do this, and what can be done to fix this?
I have tried manipulating the JS code and HTML but I can't seem to figure out what the deal is
var billAmnt = document.getElementById('billAmnt').value;
var serviceQual = document.getElementById('serviceQual').value;
var peopleAmt = document.getElementById('peopleAmt').value;
var total = billAmnt * serviceQual / peopleAmt;
function calculateTip(){
if(billAmnt === "" || serviceQual === 0){
alert("Please enter values");
}
if(peopleAmt === "" || peopleAmt <= 1){
peopleAmt = 1;
}
document.getElementById('totalTip').style.display = "block";
document.getElementById('tip').innerHTML = total;
console.log(total);
}
calcButton.addEventListener('click', calculateTip);
```
<section id="Calc">
<jumbotron id="jumbotron">
<div id="CalcContainer" class="container">
<h1>Tip Calculator</h1>
<form action="">
<p class="lead mb-40">How much was your bill?</p>
<input type="text" id="billAmnt" placeholder="Bill Amount">
<p class="lead">How was your service?</p>
<select id="serviceQual" name="serviceQual">
<option disabled selected value="0">-- Choose an Option --</option>
<option value="0.3">30% - Outstanding</option>
<option value="0.2">20% - It was good</option>
<option value="0.15">15% - It was good, but not good enough</option>
<option value="0.10">10% - It was not good</option>
<option value="0.05">5% - It was terrible, but I'm nice enough to leave a tip</option>
</select>
<p id="numOfPeople"class="lead">How many people are sharing the bill?</p>
<input id="peopleAmt" type="text" placeholder="Number of People" > people
<div class="button">
<button id="calcButton" type="button" class="btn btn-danger ">Calculate!</button>
</div>
<div id="totalTip">
<sup>$</sup><span id="tip">0.00</span>
<small id="each">each</small>
</div>
</form>
</div>
</jumbotron>
</section>
The vars you're setting are being set on page load - the values in these fields you're referencing will be blank. Thus, when attempting to apply arithmetic operations on blank values, you'll return a result that's NaN.
Move these var declarations to be set at runtime within your calculateTip() method, so the values will be pulled when the primary functionality is invoked:
function calculateTip() {
var billAmnt = document.getElementById('billAmnt').value;
var serviceQual = document.getElementById('serviceQual').value;
var peopleAmt = document.getElementById('peopleAmt').value;
var total = billAmnt * serviceQual / peopleAmt;
if (billAmnt === "" || serviceQual === 0) {
alert("Please enter values");
}
if (peopleAmt === "" || peopleAmt <= 1) {
peopleAmt = 1;
}
document.getElementById('totalTip').style.display = "block";
document.getElementById('tip').innerHTML = total;
console.log(total);
}
calcButton.addEventListener('click', calculateTip);
```
<section id="Calc">
<jumbotron id="jumbotron">
<div id="CalcContainer" class="container">
<h1>Tip Calculator</h1>
<form action="">
<p class="lead mb-40">How much was your bill?</p>
<input type="text" id="billAmnt" placeholder="Bill Amount">
<p class="lead">How was your service?</p>
<select id="serviceQual" name="serviceQual">
<option disabled selected value="0">-- Choose an Option --</option>
<option value="0.3">30% - Outstanding</option>
<option value="0.2">20% - It was good</option>
<option value="0.15">15% - It was good, but not good enough</option>
<option value="0.10">10% - It was not good</option>
<option value="0.05">5% - It was terrible, but I'm nice enough to leave a tip</option>
</select>
<p id="numOfPeople" class="lead">How many people are sharing the bill?</p>
<input id="peopleAmt" type="text" placeholder="Number of People"> people
<div class="button">
<button id="calcButton" type="button" class="btn btn-danger ">Calculate!</button>
</div>
<div id="totalTip">
<sup>$</sup><span id="tip">0.00</span>
<small id="each">each</small>
</div>
</form>
</div>
</jumbotron>
</section>
Variables are initialized before the user can enter them, on the page load. Just place your variables (billAmnt, serviceQual, peopleAmt, total) inside your calculateTip function
function calculateTip(){
var billAmnt = document.getElementById('billAmnt').value;
var serviceQual = document.getElementById('serviceQual').value;
var peopleAmt = document.getElementById('peopleAmt').value;
var total = billAmnt * serviceQual / peopleAmt;
if(billAmnt === "" || serviceQual === 0){
alert("Please enter values");
}
if(peopleAmt === "" || peopleAmt <= 1){
peopleAmt = 1;
}
document.getElementById('totalTip').style.display = "block";
document.getElementById('tip').innerHTML = total;
}
calcButton.addEventListener('click', calculateTip);
<section id="Calc">
<jumbotron id="jumbotron">
<div id="CalcContainer" class="container">
<h1>Tip Calculator</h1>
<form action="">
<p class="lead mb-40">How much was your bill?</p>
<input type="text" id="billAmnt" placeholder="Bill Amount">
<p class="lead">How was your service?</p>
<select id="serviceQual" name="serviceQual">
<option disabled selected value="0">-- Choose an Option --</option>
<option value="0.3">30% - Outstanding</option>
<option value="0.2">20% - It was good</option>
<option value="0.15">15% - It was good, but not good enough</option>
<option value="0.10">10% - It was not good</option>
<option value="0.05">5% - It was terrible, but I'm nice enough to leave a tip</option>
</select>
<p id="numOfPeople"class="lead">How many people are sharing the bill?</p>
<input id="peopleAmt" type="text" placeholder="Number of People" > people
<div class="button">
<button id="calcButton" type="button" class="btn btn-danger ">Calculate!</button>
</div>
<div id="totalTip">
<sup>$</sup><span id="tip">0.00</span>
<small id="each">each</small>
</div>
</form>
</div>
</jumbotron>
</section>

javascript appendChild show the list item then make it disappear

<div id="task-list"> <!-- Table that show tasks -->
<ul id="list"> <!--Blank table that uses JavaScript to add tasks -->
</ul>
<input type="image" src="image/plus.svg" class="add-btn-hidden" onclick="addButton()" >
</div>
<div id="hidden-add-form">
<form>
<h2 id="form-header">Add New Task</h2>
<button id="cancel" onclick="cancelButton()">X</button>
<br>Name<br>
<input type="text" id="task-name"><br>
<div class="same-line-input">
<span id="place">Place</span> <span id="department">Department</span><br>
<input type="text" id="task-place">
<select id="select">
<option value="Blank"></option>
<option value="Cleanning">Cleaning</option>
<option value="Kitchen">Kitchen</option>
<option value="Receptionist">Receptionist</option>
<option value="Beltboy">Bellboy</option>
<option value="All">All</option>
</select><br>
</div>
Description<br>
<textarea rows="10" cols="50" id="description"></textarea><br>
<input type="radio" name="urgent" value="other" id="urgent-btn"> Urgent<br>
Attachment:<br><input type="file" name="fileToUpload" id="fileToUpload"><br>
<input type="submit" id="form-submit" onclick="addTask ()">
</form>
</div>
Javascript:
function addButton (){
document.getElementById("hidden-add-form").style.visibility = "visible";
};
function cancelButton(){
document.getElementById("hidden-add-form").style.visibility= "hidden";
};
function addTask (){
let ul = document.getElementById("list");
let name = document.getElementById("task-name");
let place = document.getElementById("task-place");
let department = document.getElementById("select");
let description = document.getElementById("description");
let nameValue = "Name: " + name.value;
let li = document.createElement("li")
li.setAttribute("id", "task-on-list");
li.appendChild(document.createTextNode(nameValue));
ul.appendChild(li);
};
Functions addButton() and cancelButton() work fine but the addTask() function shows the new list-item real quick then the list item disappear. I wanted to pass the information from the form to show it in a list item of an unordered list. nameValue is just a part of my experiment

Categories