How to display Form data on click without reloading the page? - javascript

After filling in the form inputs, When i press the calculate button on the form the result does not get displayed in the salary slip box(At the bottom of the box).
But when i do refresh the page and then press the calculate button the results do get displayed in the box.
Here is the link to the code:
JsfiddleLink
"use strict";
const employeeName = document.querySelector("#input-name").value;
const grossPay = document.querySelector("#input-pay").value;
const bonus = document.querySelector("#input-bonus").value;
const allowance = document.querySelector("#input-allowance").value;
const incomeTax = document.querySelector("#input-tax").value;
const ei = document.querySelector("#input-ei").value;
const cpp = document.querySelector("#input-cpp").value;
const selectGender = document.querySelector(
'input[name="gender"]:checked'
).value;
const selectDependent = document.querySelector(
'input[name="dependent"]:checked'
).value;
const btnCalculate = document.querySelector("#submit");
const btnClear = document.querySelector("#clear");
const myForm = document.querySelectorAll(".form-control");
let inputAll = document.querySelectorAll("input");
function addition(bonus, allowance) {
let total = Number(bonus) + Number(allowance);
return total;
}
function deduction(ei, cpp) {
let total = (Number(ei) + Number(cpp)) / 100;
return total;
}
// console.log(addition(bonus, allowance));
// console.log(deduction(incomeTax, ei, cpp));
// gross salary plus additions minus deductions
// if female employee then minus 1%
// else deduction is 0
// if dependents === 2 then no deductions
// if dependents === 3 then 2 % deduction
// else if dependents === 4 then 4% deductions
// display the results on the salary slip
function genderDeduction(selectGender) {
return selectGender === "Female" ? 0.01 : null;
}
function dependentDeduction(selectDependent) {
if (selectDependent === "1") {
return null;
} else if (selectDependent === "2") {
return 0.02;
} else if (selectDependent === "3") {
return 0.04;
}
}
function incomeTaxDeduction(incomeTax) {
return Number(incomeTax) / 100;
}
// console.log(genderDeduction("Female"));
// console.log(dependentDeduction("2"));
let totalAdditions = addition(bonus, allowance);
let totalDeductions = Number(
grossPay * deduction(ei, cpp) +
grossPay *
(incomeTaxDeduction(incomeTax) -
genderDeduction(selectGender) -
dependentDeduction(selectDependent))
);
totalDeductions.toFixed(2);
function finalSalary(grossPay) {
return Number(grossPay) + totalAdditions - totalDeductions;
}
const nameSlip = document.querySelector(".name");
const grossSalary = document.querySelector(".gross-salary");
const sumOfAdditions = document.querySelector(".total-additions");
const sumOfDeductions = document.querySelector(".total-deductions");
const netSalary = document.querySelector(".final-salary");
// function salarySlip() {}
// function clearInput() {
// employeeName = "";
// grossPay = "";
// }
btnCalculate.addEventListener("click", (e) => {
e.preventDefault();
nameSlip.innerText = employeeName;
grossSalary.innerText = `$ ${grossPay}`;
sumOfAdditions.innerText = `$ ${totalAdditions}`;
sumOfDeductions.innerText = `$ ${totalDeductions.toFixed(2)}`;
netSalary.innerText = `$ ${finalSalary(grossPay)}`;
});
// btnClear.addEventListener("click", () => {
// myForm.reset();
// });

You have the following declaration:
<button
onclick="clearInput"
id="submit"
type="submit"
class="btn btn-primary"
>
Calculate
</button>
So you have to declare a function called "clearInput" to handle the button click event.
To solve your problem, you can modify the above declaration as below:
<button
id="submit"
type="submit"
class="btn btn-primary"
>
Calculate
</button>
And then add the below statements.
let myForm=document.getElementById("my-form");
myForm.addEventListener("submit",(e)=>{
//do your work here
e.preventDefault();
})

I've partially updated your code here: https://jsfiddle.net/y7hbnv18/1/
what I did:
updated all inputs to have a name property.
created a reference to the <form /> element in JS
updated the listener on submit button to be on the form instead
used the FormData API to retrieve the data from the form.
it's still somewhat in a broken state, in the last few fields, but I think you'll figure it out from here.

You need to move the code that gets the values to the body of the event handler function.
btnCalculate.addEventListener("click", (e) => {
e.preventDefault();
const employeeName = document.querySelector("#input-name").value;
const grossPay = document.querySelector("#input-pay").value;
const bonus = document.querySelector("#input-bonus").value;
const allowance = document.querySelector("#input-allowance").value;
const incomeTax = document.querySelector("#input-tax").value;
const ei = document.querySelector("#input-ei").value;
const cpp = document.querySelector("#input-cpp").value;
const selectGender = document.querySelector(
'input[name="gender"]:checked'
).value;
const selectDependent = document.querySelector(
'input[name="dependent"]:checked'
).value;
let totalAdditions = addition(bonus, allowance);
let totalDeductions = Number(
grossPay * deduction(ei, cpp) +
grossPay *
(incomeTaxDeduction(incomeTax) -
genderDeduction(selectGender) -
dependentDeduction(selectDependent))
);
totalDeductions.toFixed(2);
nameSlip.innerText = employeeName;
grossSalary.innerText = `$ ${grossPay}`;
sumOfAdditions.innerText = `$ ${totalAdditions}`;
sumOfDeductions.innerText = `$ ${totalDeductions.toFixed(2)}`;
netSalary.innerText = `$ ${finalSalary(grossPay, totalAdditions, totalDeductions)}`;
});
Also update the finalSalary function so you can pass in totalAdditions and totalDeductions the signature should be
function finalSalary(grossPay, totalAdditions, totalDeductions)
You may also need to change the button type to button from submit to stop the form being submitted as this will refresh the page.
<button
onclick="clearInput"
id="submit"
type="button"
class="btn btn-primary"
>
Calculate
</button>

Related

How to add new box with size of the last box

I have a problem with adding a function which will create an amount of boxes with rising size and when i try to add more I will start from the size of the previous last box.
So far i have a code like this:
function getRandomHexColor() {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
const input = document.querySelector("#controls>input");
const createBtn = document.querySelector("button[data-create]");
const destroyBtn = document.querySelector("button[data-destroy]");
const boxCollection = document.querySelector("#boxes");
const createBoxes = (amount) => {
amount = input.value;
for (let i = 0; i < amount; i += 1) {
let newBox = document.createElement("div");
newBox.style.height = `${30 + 10 * i}px`;
newBox.style.width = `${30 + 10 * i}px`;
newBox.style.background = getRandomHexColor();
boxCollection.insertAdjacentElement("beforeend", newBox);
}
};
createBtn.addEventListener("click", createBoxes);
const destroyBoxes = () => {
boxCollection.innerHTML = "";
};
destroyBtn.addEventListener("click", destroyBoxes);
I was thinking about adding a new var which will be the lastChild of const boxCollection and add it to height and width of newBox. Am I thinking right?
You can either create a variable with the current number of boxes or you can just count the current number each time you add more. In the example the current number (currentCount) is based on the length of a querySelectorAll().
function getRandomHexColor() {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
const boxCollection = document.querySelector("#boxes");
const createBoxes = e => {
e.preventDefault();
let amount = parseInt(e.target.amount.value);
let currentCount = boxCollection.querySelectorAll('div').length;
Object.keys([...Array(amount)]).forEach(i => {
let incVal = parseInt(i) + currentCount;
let newBox = document.createElement("div");
newBox.style.height = `${30 + 10 * incVal}px`;
newBox.style.width = `${30 + 10 * incVal}px`;
newBox.style.background = getRandomHexColor();
boxCollection.insertAdjacentElement("beforeend", newBox);
});
};
const destroyBoxes = e => {
e.preventDefault();
boxCollection.innerHTML = "";
};
document.forms.create.addEventListener("submit", createBoxes);
document.forms.destroy.addEventListener("submit", destroyBoxes);
<form name="create">
<input type="number" name="amount" />
<button>Create</button>
</form>
<form name="destroy">
<button>Destroy</button>
</form>
<div id="boxes"></div>
You could hold the latest size of the box in a var.
function getRandomHexColor() {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
const input = document.querySelector("#controls>input");
const createBtn = document.querySelector("button[data-create]");
const destroyBtn = document.querySelector("button[data-destroy]");
const boxCollection = document.querySelector("#boxes");
let currentBoxSize = 30 // starting box size
const BOX_SIZE_INCREMENT = 10 // increment size
const createBoxes = (amount) => {
amount = input.value;
for (let i = 0; i < amount; i += 1) {
let newBox = document.createElement("div");
newBox.style.height = `${currentBoxSize}px`;
newBox.style.width = `${currentBoxSize}px`;
newBox.style.background = getRandomHexColor();
boxCollection.insertAdjacentElement("beforeend", newBox);
currentBoxSize += BOX_SIZE_INCREMENT
}
};
createBtn.addEventListener("click", createBoxes);
const destroyBoxes = () => {
boxCollection.innerHTML = "";
};
destroyBtn.addEventListener("click", destroyBoxes);
Just store the last input value in a variable, or if you want to preserve the state, you can store it in locale storage, and when you click create boxes, sum it with the value with the new input value.
function getRandomHexColor() {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
const input = document.querySelector("#controls>input");
const createBtn = document.querySelector("button[data-create]");
const destroyBtn = document.querySelector("button[data-destroy]");
const boxCollection = document.querySelector("#boxes");
let lastInputValue = 0;
const createBoxes = (amount) => {
amount = input.value + lastInputValue;
for (let i = 0; i < amount; i += 1) {
let newBox = document.createElement("div");
newBox.style.height = `${30 + 10 * i}px`;
newBox.style.width = `${30 + 10 * i}px`;
newBox.style.background = getRandomHexColor();
boxCollection.insertAdjacentElement("beforeend", newBox);
}
lastInputValue = amount;
};
createBtn.addEventListener("click", createBoxes);
const destroyBoxes = () => {
boxCollection.innerHTML = "";
};
destroyBtn.addEventListener("click", destroyBoxes);

How to automatically add and update the price total when adding an item with price

I have been learning javascript, i'm on my second project called "expense tracker" i have been able to use DOM and functions but could not execute right on the operators.
I have 2 input text the first is "item name" and the second is "price".
I have 2 buttons first is "add" and 2nd is "deduct".
The problem is Im so confused to create functions on the operators that able to get the total price and auto update the total whenever I add items.
I want to achieve:
When ever I add Item the current total price will be updated automatically.
When ever I deduct item the current total price will be updated automatically.
This the Javascript. I can able add and append items and price but dont know how to add and deduct with automatic price total.
const itemname = document.querySelector('#itemname');
const price = document.querySelector('#price');
//set requirements and limitations
const isRequired = value => value === '' ? false : true;
//set error trapping and message
const showError = (input, message) => {
const formgroup = input.parentElement;
formgroup.classList.remove('success');
formgroup.classList.add('error');
const error = formgroup.querySelector('small');
error.textContent = message;
}
const showSuccess = (input, message) => {
const formgroup = input.parentElement;
formgroup.classList.remove('error');
formgroup.classList.add('success');
const error = formgroup.querySelector('small');
error.textContent = message;
}
// Verifying fields if correct
const checkItemname = () =>{
let valid = false;
const itemnameTrim = itemname.value.trim();
const priceTrim = price.value.trim();
if(!isRequired(itemnameTrim)){
showError(itemname, "Pls type item name!");
}
else if(!isRequired(priceTrim)){
showError(price, "Pls type price!");
}
else{
showSuccess(itemname);
showSuccess(price);
addItem();
valid = true;
}
return valid;
}
const addItem = () => {
const itemnameTrim = itemname.value.trim();
const tableRowItem = document.createElement("tr");
const tableDataItem = document.createElement("td");
const tableTxtnode = document.createTextNode(itemnameTrim);
tableRowItem.appendChild(tableDataItem);
tableDataItem.appendChild(tableTxtnode);
document.getElementById("td-item").appendChild(tableRowItem);
const priceTrim = price.value.trim();
const tableDataPrice = document.createElement("td");
const tableTxtnodePrice = document.createTextNode(priceTrim);
tableRowItem.appendChild(tableDataPrice);
tableDataPrice.appendChild(tableTxtnodePrice);
document.getElementById("itemname").value = "";
document.getElementById("price").value = "";
}
//Deduct button
const deductItem = () => {
const itemnameTrim = itemname.value.trim();
const tableRowItem = document.createElement("tr");
const tableDataItem = document.createElement("td");
const tableTxtnode = document.createTextNode(itemnameTrim);
tableRowItem.className = 'redtext';
console.log(tableRowItem);
tableRowItem.appendChild(tableDataItem);
tableDataItem.appendChild(tableTxtnode);
document.getElementById("td-item").appendChild(tableRowItem);
const priceTrim = price.value.trim();
const tableDataPrice = document.createElement("td");
const tableTxtnodePrice = document.createTextNode(priceTrim);
tableRowItem.appendChild(tableDataPrice);
tableDataPrice.appendChild(tableTxtnodePrice);
document.getElementById("itemname").value = "";
document.getElementById("price").value = "";
}
//Call the buttons and evoke functions
const deductBtn = document.querySelector('#deductBtn')
const addBtn = document.querySelector('#addBtn')
addBtn.addEventListener("click", function(){
checkItemname()});
deductBtn.addEventListener("click", function(){
deductItem()});
$(document).ready(function(){
//iterate through each textboxes and add keyup
//handler to trigger sum event
$(".txt").each(function() {
$(this).keyup(function(){
calculateSum();
});
});
});
function calculateSum() {
var sum = 0;
//iterate through each textboxes and add the values
$(".txt").each(function() {
//add only if the value is number
if(!isNaN(this.value) && this.value.length!=0) {
sum += parseFloat(this.value);
}
});
//.toFixed() method will roundoff the final sum to 2 decimal places
$("#sum").html(sum.toFixed(2));
}

How to change min value to current page when button is pressed in input range?

I want to change the value like this when I press the next button while on the current page.
I wrote the code like this, but it doesn't work at all:
el.delegate(".nextbtn", "click", function (event) {
const current = $(event.currentTarget) // =.nextbtn
const currentR = $(".pagination-range")
let pageNumber = +currentR.val() // =currentPage
let minV = +currentR.attr("min")
let maxV = +currentR.attr("max")
if (self.getTotalPage >= maxV) {
currentR.attr({
min: pageNumber,
max: pageNumber + 4,
})
}
})
What's wrong with this code? Thank you in advance.
Here is pure javascript solution for you. I defined my own $ as shorthand function, which utilizes querySelector, so its similar to jQuery.
const $ = (s) => document.querySelector(s);
const rng = $("#rng");
const button = $("#biggerMax");
button.addEventListener("click", () => {
console.log("adding max value by 4");
let rngMax = rng.getAttribute("max");
let newMax = parseInt(rngMax)+4;
rng.setAttribute("max", newMax );
});
<input id="rng" type=range min=2 max=5 step=1>
<button id="biggerMax">Bigger max</button>

Keep Todo Results after browser refreshing

I created a todo app to add and remove tasks on the page.
however i would like to keep todo results when browser refreshed .
Is that possible to make this like storing data on db or any storage to save these results?
any idea to make this to save data ??
Now I posted the complete code hereee! because i cant posted code here before
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let irp = document.querySelector(".date");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
let addBr = () => {
btn1.addEventListener("click", addBr);
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (irp.value);
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
btn1.addEventListener("click", addBr);
// Call `addBr` once to add the initial element
addBr();
<html>
<body>
<div class="bs">
<input type="text" class="input">
<input type="date" class="date">
<button class="btn">
Add
</button>
</div>
</body>
</html>
TL;DR: use localStorage to read the items at page load and write the items when they change, like in the final version
To keep your todo entries, you need to store it in a Database. This can be either a local database in the website like localStorage. Or you need to build a backend which is connected to a Database and send and load the Data from there.
localStorage example:
const items = [{ name: "My Todo" }, { name: "My Todo 2" }];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
Including your code:
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
const items = getItems() || [];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
let addBr = (item) => {
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (item ? item.name : inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (item ? item.name : irp.value);
if (!item) {
items.push({ name: inp.value });
setItems();
}
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
for (const item of items) {
addBr(item);
}
btn1.addEventListener("click", () => addBr());

I'm trying to pass event target values to another function

I set up two events, one in feet and one in inches. I'm trying to grab the value of each event which would be feet and inches but I can't because of each event's scope. Is there a way to pass both values into my totalHeight function so that I can add the two values together?
const justFeet = totalFeet.addEventListener('input', (e) => {
const heightInFeet = e.target.value;
let displayFeet = document.createElement('h3')
displayFeet.textContent = heightInFeet * 12
// totalInches.appendChild(displayFeet)
})
const justInches = inches.addEventListener('input', (e) => {
const addOnInches = e.target.value;
let displayInches = document.createElement('h3')
displayInches.textContent = addOnInches
// totalInches.appendChild(displayInches)
})
function totalHeight (feet, inches) {
const finalTotal = feet + inches;
let finalHeight = document.createElement('h3')
finalHeight.textContent = finalTotal
totalInches.appendChild(finalHeight)
}
totalHeight(displayFeet, displayInches)
An example of what it looks like you are trying to do. There's more you need to do, for example I used integers below but you could use floating numbers and perhaps add better handling for isNaN().
<html>
<style>
</style>
Feet:<input id="feet" type="number"></input>
Inches:<input id="inches" type="number"></input>
<h3>Feet converted to inches: <span id="displayFeetToInches"></span></h3>
<h3>Inches: <span id="displayInches"></span></h3>
<h3>Total inches:<span id="finalHeight"></span></h3>
<script>
const feet = document.getElementById("feet");
const inches = document.getElementById("inches");
const total = document.getElementById("total"); //in inches
const displayFeetToInches = document.getElementById("displayFeetToInches"); //in inches
const displayInches = document.getElementById("displayInches"); //in inches
const justFeet = feet.addEventListener('input', (e) => {
console.log('justFeet');
const heightInFeet = e.target.value;
displayFeetToInches.textContent = heightInFeet * 12;
totalHeight();
})
const justInches = inches.addEventListener('input', (e) => {
console.log('justInches');
const addOnInches = e.target.value;
displayInches.textContent = addOnInches
totalHeight();
})
function totalHeight (feet, inches) {
console.log('totalinches');
const ftToInches = displayFeetToInches.textContent;
const addOn = displayInches.textContent;
const finalTotal = parseInt(ftToInches) + parseInt(addOn);
finalHeight.textContent = finalTotal
}
</script>
</html>

Categories