UI not updating document.getElementById("").textContent - javascript

Posting this again because I did not have enough code posted before and the title was wrong. I created an object from a form that returns a grossIncome. In Js I have a function that will calculate the ei based on the gross income using 2 if statements and then updates it in the UI. When I console.log (), it appears to see the value and correctly, however the UI does not update.
index.html
<form name="formFill" id="form">
<input name="income" type="number" inputmode="numeric" id="incomeTextBox" placeholder="Gross Income" required>
<select name="workingProvince" id="provinces">
<option value="Ontario">Ontario</option>
<option value="Quebec">Quebec</option>
...
</select>
<button type="submit" id="calculate">Calculate</button>
</form>
<div class="ei">
<h3>EI Deduction</h3>
<p id="eiValue">- $0</p>
</div>
<script type="module">
import { submitForm } from './javascript/taxCalculatorIndex.js'
document.getElementById('form').addEventListener('submit', submitForm)
</script>
calculations.js
export const calculateEITax = (grossIncome) => {
console.log ('calculateEITaxGross:', grossIncome)
let ei;
if (grossIncome <= 60300) {
console.log ('grossIncome <= 60300:', grossIncome <= 60300)
// console.log ('ei:', grossIncome * 0.0158 )
ei = grossIncome * 0.0158;
}
else {
ei = 60300 * 0.158;
}
return ei;
}
index.js
import {calculateEITax} from './calculations.js'
export const submitForm = (event) => {
event.preventDefault()
const form = document.getElementById('form');
const data = new FormData(form);
const dataObject = {};
for (const [key, value] of data.entries()) {
dataObject[key] = value;
};
let grossIncome = dataObject.income;
let province = dataObject.workingProvince;
calculateTax(grossIncome, province);
}
const calculateTax = (grossIncome, province) => {
const eiTax = calculateEITax(grossIncome);
console.log("eiTax: ", eiTax)
updateDOM(eiTax);
}
const updateDOM = (eiTax) => {
document.getElementById("eiValue").textContent = `- $${eiTax}`;
console.log ("eiValue:", document.getElementById("eiValue").textContent = `- $${eiTax}` )
}
console.log output:
calculateEITaxGross: 30000
calculations.js:423 grossIncome <= 60300: true
index.js:95 eiTax: 474.00000000000006
index.js:127 eiValue: - $474.00000000000006
But my UI updates undefined
Anyone know why this is?

Related

Script wont display the total prices

Im new to coding. Can anyone see why my script wont display the total prices of the different providers when I click calculate button? (I have two json files for data consumption.json and providers.json) I only want someone to look over and look for any mistakes I can have made.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Energy Consumption Calculator</title>
</head>
<body>
<h1>Energy Consumption Calculator</h1>
<form id="calculation-form">
<div>
<label for="fixedPrice">Fixed Price:</label>
<input type="number" id="fixedPrice" name="fixedPrice">
</div>
<div>
<label for="variablePrice">Variable Price:</label>
<input type="number" id="variablePrice" name="variablePrice">
</div>
<div>
<label for="spotPrice">Spot Price:</label>
<input type="number" id="spotPrice" name="spotPrice">
</div>
<button type="submit" onclick="calculatePrice()">Calculate</button>
</form>
<div id="output"></div>
</main>
</body>
</html>
app.js
async function getData(url) {
const response = await fetch(url);
console.log(response);
return response.json();
}
async function calculatePrice() {
const consumptionData = await getData("consumption.json");
const providersData = await getData("providers.json");
let prices = [];
let fixedtotalPrice = 0;
let variabletotalPrice = 0;
let hourlytotalPrice = 0;
let monthlytotalPrice = 0;
for (const provider of providersData) {
for (const consumption of consumptionData) {
if (provider.pricingModel === "fixed") {
// Get the fixedPrice value from user input
const fixedPrice = parseFloat(document.getElementById("fixedPrice").value);
fixedtotalPrice += fixedPrice * consumption.consumption;
} else if (provider.pricingModel === "variable") {
// Get the variablePrice value from user input
const variablePrice = parseFloat(document.getElementById("variablePrice").value);
variabletotalPrice += consumption.consumption * variablePrice;
} else if (provider.pricingModel === "spotPrice") {
// Get the spotPrice value from user input
const spotPrice = parseFloat(document.getElementById("spotPrice").value);
hourlytotalPrice += consumption.consumption * spotPrice;
} else if (provider.pricingModel === "spotPrice") {
// Get the spotPrice value from user input
const spotPrice = parseFloat(document.getElementById("spotPrice").value);
monthlytotalPrice += spotPrice * consumption.consumption;
}
}
}
prices.push({ provider: "Vest Energi", totalPrice: fixedtotalPrice });
prices.push({ provider: "Øst Energi", totalPrice: variabletotalPrice });
prices.push({ provider: "Nord Energi", totalPrice: hourlytotalPrice });
prices.push({ provider: "Syd Energi", totalPrice: monthlytotalPrice });
let output = "<ul>";
for (const price of prices) {
output += `<li>${price.provider}: ${price.totalPrice}</li>`;
}
output += "</ul>";
document.getElementById("output").innerHTML = output;
}
const form = document.getElementById("calculation-form");
form.addEventListener("submit", function (event) {
event.preventDefault();
calculatePrice();
});
Can't find the mistake.Dont think it has anything to with the json files, but something in my code.

Liveserach passing values ​from other object fields iterates

I put a snippet to make the idea better.
Type any character in the Find field, in the console you will see the log of the dataAdd object, if now we change the value of the select Department and type any character again, the log becomes double, with the value of Department previous and current one, and if you repeat this, each time you add the value in the log.
I need the passed value to send it on the server side to filter the search by department but this way it can't work.
Can you help me, I'm going crazy
const $ = id => document.getElementById(id);
let ajaxInProgress = false;
const ajaxGet = async (elab, q, dataAdd) => {
if (ajaxInProgress) return;
ajaxInProgress = true;
let url;
if (dataAdd != null) {
url = "/utility/cerca/getLiveSearch/" + elab + "/" + q + "/" + btoa(JSON.stringify(dataAdd));
} else {
url = "/utility/cerca/getLiveSearch/" + elab + "/" + q;
}
let response = await fetch(url),
data = await response.text();
if (response.ok) {
ajaxInProgress = false;
return data;
} else if (response.status === 404) {
ajaxInProgress = false;
return false;
} else {
ajaxInProgress = false;
return "Error: " + response.status;
}
};
const liveSearch = (id, elCont, elab, dataAdd) => {
const el = document.querySelector("input" + id);
// If I can't find the execution block element
if (!el) return !1;
el.classList.add("liveSearch");
el.parentElement.classList.add("position-relative");
el.setAttribute("autocomplete", "off");
// If the item doesn't already exist, I create it
if (!$(elCont)) {
// Appendo elemento al campo input
let lsContainer = document.createElement("div");
lsContainer.id = elCont;
lsContainer.classList.add("liveSearchContent", "shadow", "bg-white", "border", "border-2", "rounded-2", "position-absolute", "overflow-auto", "mt-1", "d-none");
el.after(lsContainer);
}
// To KeyUp
el.addEventListener("keyup", ls => {
// I get the typed value
let q = el.value,
innerResult = document.querySelector("#" + elCont);
if (q != "") {
// Log data send from input field
console.log(dataAdd);
ajaxGet(elab, q, dataAdd).then(html => {
// Resize liveSearch
resizeLiveSearch();
// I hang the results
innerResult.innerHTML = html + ' - ' + q;
// Hide/Show liveSearch
ls.target.value.length < 1 ? innerResult.classList.add("d-none") : innerResult.classList.remove("d-none");
});
} else {
// Hide/Show liveSearch
ls.target.value.length < 1 ? innerResult.classList.add("d-none") : innerResult.classList.remove("d-none");
}
});
el.addEventListener("focus", el => {
el.target.closest("div").querySelector(".liveSearchContent").classList.remove("d-none");
});
// When I resize the window, I resize the livesearch
window.onresize = resizeLiveSearch;
document.addEventListener("click", e => {
let box = document.querySelector(".liveSearchContent");
if (box) {
if (box.contains(e.target) || !e.target.classList.contains("liveSearch")) {
handleBlur();
} else {
return false;
}
}
});
};
let resizeLiveSearch = () => {
document.querySelectorAll(".liveSearch").forEach(e => {
e.closest("div").querySelector(".liveSearchContent").style.width = e.offsetWidth + "px";
});
};
let handleBlur = () => {
document.querySelectorAll(".liveSearchContent").forEach(el => {
el.classList.add("d-none");
});
};
// -- Piece of code that interacts with liveSearch
document.addEventListener("DOMContentLoaded", () => {
let idReparto = $("id_reparto"),
idEvento = $("id_evento"),
evento = $("evento"),
reparto = idReparto.value;
idReparto.addEventListener("change", el => {
console.clear();
idEvento.value = evento.value = "";
reparto = el.target.value;
liveSearch("#evento", "searchEventoRicerca", "evento_reparto", { reparto: reparto });
});
liveSearch("#evento", "searchEventoRicerca", "evento_reparto", { reparto: $("id_reparto").value });
$("searchEventoRicerca").addEventListener("click", el => {
let elt = el.target,
evento2 = "";
if (elt.matches(".srel")) {
evento2 = elt.getAttribute("id");
el.preventDefault();
elt.blur();
evento.value = elt.text;
idEvento.value = evento2;
pdvEvento.value = idPdv.value = "";
// Mostro pdv_evento e occulto pdv
pdvEvento.parentElement.classList.remove("d-none");
console.log(evento2);
}
});
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<form class="mb-5 mt-2 mx-2">
<div class="row g-3">
<input type="hidden" id="id_evento" name="id_evento" value="">
<div class="col-md-3">
<label for="id_reparto" class="form-label">Department</label>
<select class="form-select" id="id_reparto" name="id_reparto" title="id_reparto">
<option value="1">Dep 1</option>
<option value="3">Dep 3</option>
<option value="2" selected="selected">Dep 2</option>
</select>
</div>
<div class="col-md-6">
<label for="evento" class="form-label">Find</label>
<input type="text" class="form-control liveSearch" placeholder="Type any character" id="evento" name="evento" value="" autocomplete="off">
<div id="searchEventoRicerca" class="liveSearchContent shadow bg-white border border-2 rounded-2 position-absolute overflow-auto mt-1 d-none"></div>
</div>
</div>
</form>

How do i check if <input type="text"/> has only spaces in React JS?

I need to get the value of a input to be displayed in real time but I need to show some default text if the Input is empty or only spaces, but I cant seem to get it to work
const [productName, setProductName] = useState("");
const defaultProductName = "Name";
const handleChange = (event) => {
setProductName(event.target.value);
const inputValue = event.target.value;
const inputId = document.getElementById("productNameInput").innerHTML;
if (event.target.value.length == 0) {
document.getElementById("productNameID").innerHTML = defaultProductName;
} else {
document.getElementById("productNameID").innerHTML = inputValue;
}
};
<div className="productName" id="productNameID">
{defaultProductName}
</div>
<form>
<input type="text" id="productNameInput" onChange={handleChange} />
</form>
you can try:
if(document.getElementByID("productNameInput").value == " " | document.getElementByID("productNameInput").value.length == 0){
console.log("Input is empty")
}

React js Calculator final result shows inside console.log but not in the browser

Blockquote I CAN NOT PUSH MY RESULT TO THE PAGE, BUT new1Num and new2Num as well as newOper is
Blockquote reflected just fine. result only shows up inside console.log(result); I already tried taking var result outside of main function and tried const and also tried "let [result, setNewAnsw] = useState(0); " just like i did for new1Num but still no luck.
import React, { useState } from 'react';
// If the component accepts a parameter, this is referred to as a "prop."
// Props allows to pass values INTO my components from a parent document / component.
function Calculator (props)
{ // Every component should return JSX.
const [new1Num, setNew1Num] = useState(0);
const [new2Num, setNew2Num] = useState(0);
const [newOper, setNewOper] = useState('add');
// let [result, setNewAnsw] = useState(0);
var result;
const onFormSubmit = event =>
{
event.preventDefault();
console.log(new1Num);
const a = parseFloat(new1Num);
console.log(newOper);
console.log(new2Num);
const b = parseFloat(new2Num);
let result;
if (newOper == 'add'){
result = a + b;
console.log(result);
}
else if (newOper == 'subtract'){
result = a - b;
}
else if (newOper == 'divide' && b !=0){
result = a / b;
}
else if (newOper == 'multiply'){
result = a * b;
}
return newResult = result; //IN THIS SECTION I CAN'T TAKE MY RESULT TO RENDER INSIDE DOM
}
let heading = props.heading;
let input1 = props.input1;
let input2 = props.input2;
let newResult = props.newResult;
return (
<div>
<h1> { heading } </h1>
<form onSubmit = {onFormSubmit}>
<h2> { input1 } </h2>
<input
type="number" min="0" step="1"
onChange={e => { setNew1Num( e.target.value ) }}
value={new1Num}
className='field' />
<h2>Operator</h2>
<select
onChange={e => { setNewOper( e.target.value ) }}
value={newOper}
className='oper' >
<option value='add'>+</option>
<option value='subtract'>-</option>
<option value='divide'>/</option>
<option value='multiply'>*</option>
</select>
<h2> {input2}</h2>
<input
type="number" min="0" step="1"
onChange={e => { setNew2Num( e.target.value ) }}
value={new2Num}
className='field' />
<h2></h2>
<input type='submit' className='submitBtn success' value='Submit'/>
<h3>RESULT:
{new1Num}
{newOper}
{new2Num}
{newResult}
</h3>
</form>
</div>
);//new1Num and newOper and new2Num are populating inside browser just fine
}
export default Calculator
In order to publish the result to the page react would need to rerender. This can be achieved by saving the result into state and updating when completing a computation.
Use const [result, setNewAnsw] = useState(0); to set/access the result, and setNewAnsw(result) in the form's onFormSubmit callback. Delete let newResult = props.newResult; as newResult isn't passed as a prop, it's computed in state. Also, use "===" vs "==" for comparisons.
...
const [result, setNewAnsw] = useState(0);
const onFormSubmit = (event) => {
event.preventDefault();
console.log(new1Num);
const a = parseFloat(new1Num);
console.log(newOper);
console.log(new2Num);
const b = parseFloat(new2Num);
let result;
if (newOper === "add") {
result = a + b;
console.log(result);
} else if (newOper === "subtract") {
result = a - b;
} else if (newOper === "divide" && b) { // b any value other than 0 is truthy!
result = a / b;
} else if (newOper === "multiply") {
result = a * b;
}
setNewAnsw(result);
};
...

Having issues with validation of input field

I'm trying to validate an input field. When i try to submit without filling in something, it gives me the error i made: please start your question with: will i ever. So i'm trying to check wether the text that the user types into the field, starts with: will i ever.
However, when i type a single (or more) random character(s), it just submits the form. I want it to check if the input starts with those fixed tree words, otherwise, no submission.
{
const handleSubmitForm = e => {
const $form = e.currentTarget;
if (!$form.checkValidity()) {
e.preventDefault();
const field = $form.querySelector('.question_field');
showValidationInfo(field);
//$form.querySelector('.error').innerHTML = 'Some errors occured';
} else {
console.log('Form is valid => submit form');
}
};
const showValidationInfo = field => {
console.log(field);
let message;
if (field.validity.valueMissing) {
message = 'Please fill in a question starting with: Will i ever';
}
if (field.validity.typeMismatch) {
message = 'Type not right';
}
if (field.validity.rangeOverflow) {
const max = field.getAttribute('max');
message = 'Too big, max ${max}';
}
if (field.validity.rangeUnderflow) {
const min = field.getAttribute('min');
message = 'Too small, min ${min}';
}
if (field.validity.tooShort) {
const min = field.getAttribute('minlength');
message = 'Too short, minimum length is ${min}';
}
if (field.validity.tooLong) {
const max = field.getAttribute('maxlength');
message = 'Too long, maximum length is ${max}';
}
if (!field.value.toLowerCase().startsWith("will i ever")) {
message = 'Start your question with: Will i ever';
}
if (message) {
field.parentElement.querySelector('.error').textContent =
message;
field.parentElement.querySelector('.error').style.color = "red";
}
};
const handeInputField = e => {
const $field = e.currentTarget;
if ($field.checkValidity()) {
$field.parentElement.querySelector('.error').textContent = '';
if ($field.form.checkValidity()) {
$field.form.querySelector('.error').innerHTML = '';
}
}
};
const handeBlurField = e => {
const $field = e.currentTarget;
showValidationInfo($field);
};
const addValidationListeners = fields => {
fields.forEach($field => {
$field.addEventListener('input', handeInputField);
$field.addEventListener('blur', handeBlurField);
});
};
const init = () => {
const $form = document.querySelector('form');
$form.noValidate = true;
$form.addEventListener('submit', handleSubmitForm);
const fields = $form.querySelectorAll('.input');
addValidationListeners(fields);
};
init();
}
<div class="name_wrapper">
<form autocomplete="off" class="form_question" action="answer.html">
<label class="name question" for="name">Ask me a question</label>
<div class="question_wrapper">
<p class="error">Start your question with: Will i ever...</p>
<input class="field question_field" type="text" name="question" placeholder="Will i ever..." value="" required>
</div>
<input id="button" class="answr-btn btn-question" type="submit" value="answer it!">
<input autocomplete="false" name="hidden" type="text" style="display:none;">
</form>
</div>
This line makes no sense:
const fields = $form.querySelectorAll('.input');
There are no HTML elements with class="input" in your form.
Did you mean $form.querySelectorAll('input')?
The problem is how you are handling the validation, the key is in this line if (!$form.checkValidity()) { this will not check if your string starts with Will i ever you have to do it manually before the if, here you have an alternative solution:
{
const handleSubmitForm = e => {
const $form = e.currentTarget;
const field = $form.querySelector('.question_field');
//here we validate the form manually
const message = showValidationInfo(field);
//if a message is found we show the error on the DOM, if is undefined we have no errors and we can submit the form
if (message) {
e.preventDefault();
$form.querySelector('.error').innerHTML = message;
$form.querySelector('.error').style.color = "red";
} else {
console.log('Form is valid => submit form');
}
};
const showValidationInfo = field => {
if (field.validity.valueMissing) {
return 'Please fill in a question starting with: Will i ever';
}
if (field.validity.typeMismatch) {
return 'Type not right';
}
if (field.validity.rangeOverflow) {
const max = field.getAttribute('max');
return 'Too big, max ${max}';
}
if (field.validity.rangeUnderflow) {
const min = field.getAttribute('min');
return 'Too small, min ${min}';
}
if (field.validity.tooShort) {
const min = field.getAttribute('minlength');
return 'Too short, minimum length is ${min}';
}
if (field.validity.tooLong) {
const max = field.getAttribute('maxlength');
return 'Too long, maximum length is ${max}';
}
if (!field.value.toLowerCase().startsWith("will i ever")) {
return 'Start your question with: Will i ever';
}
return undefined;
};
const handeInputField = e => {
const $field = e.currentTarget;
if ($field.checkValidity()) {
$field.parentElement.querySelector('.error').textContent = '';
if ($field.form.checkValidity()) {
$field.form.querySelector('.error').innerHTML = '';
}
}
};
const handeBlurField = e => {
const $field = e.currentTarget;
showValidationInfo($field);
};
const addValidationListeners = fields => {
fields.forEach($field => {
$field.addEventListener('input', handeInputField);
$field.addEventListener('blur', handeBlurField);
});
};
const init = () => {
const $form = document.querySelector('form');
$form.noValidate = true;
$form.addEventListener('submit', handleSubmitForm);
const fields = $form.querySelectorAll('.input');
addValidationListeners(fields);
};
init();
}
<div class="name_wrapper">
<form autocomplete="off" class="form_question" action="answer.html">
<label class="name question" for="name">Ask me a question</label>
<div class="question_wrapper">
<p class="error">Start your question with: Will i ever...</p>
<input class="field question_field" type="text" name="question" placeholder="Will i ever..." value="" required>
</div>
<input id="button" class="answr-btn btn-question" type="submit" value="answer it!">
<input autocomplete="false" name="hidden" type="text" style="display:none;">
</form>
You have uncommented backtick at occured `;

Categories