I'm writing a JavaScript in Google Apps that will write monthly dollars to a spreadsheet from an HTML user input.
It functions where it take input from the user via html input. I then use a Class that captures and calculates as the user is entering content, which is actively writing to the screen.
It needs to take in positive and negative numbers. While it takes the input of the user, it only displays the number as a positive amount, even when it is a negative. In addition, it is not calculating correctly. I noticed that if the number has a comma, for example 1,000, it drops everything after the comma. I am sharing below the header script and then script in the body of the HTML file as well as the html code with the function. Lastly, I am using Bootstrap which functions fine for other areas of the code.
Head script
<script>
function toFinalNumberFormat(controlToCheck) {
var enteredNum = '' controlToCheck.value;
enteredNum = enteredNum.replace(/[^0-9\.] /g, '');
controlToCheck.value = Number(enteredNum).toLocaleString();
}
</script>
Script in HTML body
document.getElementsByClassName("add-input").addEventListener("input", sumTotal); //listener when numbers are inputted into monthly spend fields
function sumTotal () {
var inputs = document.getElementsByClassName('add-input')
var totalSum = 0
for ( let i=0; i < inputs.length; i ) {
totalSum = parseFloat(inputs[i].value || 0, 10)
}
var total = document.getElementById("total");
total.value = totalSum.toFixed(2).replace(/\d(?=(\d{3}) \.)/g, '$&,');
}
This is the HTML snippet
<h5>Monthly Spend</h5>
<div >
<div class = "row">
<div >
<input type="text" id="jan" aria-placeholder="January" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="jan">January<br>$</label>
</div>
<div >
<input type="text" id="feb" aria-placeholder="February" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="feb">February<br>$</label>
</div>
<div >
<input type="text" id="mar" aria-placeholder="March" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="mar">March<br>$</label>
</div>
<div >
<input type="text" id="apr" aria-placeholder="April" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="apr">April<br>$</label>
</div>
<div >
<input type="text" id="may" aria-placeholder="May" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="may">May<br>$</label>
</div>
<div >
<input type="text" id="jun" aria-placeholder="June" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="jun">June<br>$</label>
</div>
</div>
<div class = "row">
<div >
<input type="text" id="jul" aria-placeholder="July" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="jul">July<br>$</label>
</div>
<div >
<input type="text" id="aug" aria-placeholder="August" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="aug">August<br>$</label>
</div>
<div >
<input type="text" id="sep" aria-placeholder="September" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="sep">September<br>$</label>
</div>
<div >
<input type="text" id="oct" aria-placeholder="October" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="$0.00">
<label for="oct">October<br>$</label>
</div>
<div >
<input type="text" id="nov" aria-placeholder="November" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="nov">November<br>$</label>
</div>
<div >
<input type="text" id="dec" aria-placeholder="December" onblur="toFinalNumberFormat(this);" oninput="sumTotal()" placeholder="0.00">
<label for="dec">December<br>$</label>
</div>
</div>
<div class = "row">
<div >
<h3>Total: $<output type="number" id="total"></output></h3>
</div>
Can someone please point out what is wrong with the code? Thanks!
CodePudding user response:
document.getElementsByClassName()
returns a list of elements, you need to iterate over it to add all the event listeners.
You need to remove the commas calling parseFloat()
on each value in the loop, not after you calculate the total, because parseFloat()
can't parse numbers with comma separators.
document.querySelectorAll(".add-input").forEach(input => {
input.addEventListener("input", sumTotal);
input.addEventListener("blur", () => toFinalNumberFormat(input));
});
function sumTotal() {
var inputs = document.getElementsByClassName('add-input');
var totalSum = 0
for (let i = 0; i < inputs.length; i ) {
totalSum = parseFloat(inputs[i].value.replace(/[^-\d.]/g, '') || 0);
}
var total = document.getElementById("total");
total.value = totalSum.toFixed(2);
}
function toFinalNumberFormat(controlToCheck) {
var enteredNum = '' controlToCheck.value;
enteredNum = enteredNum.replace(/[^-\d.]/g, '');
controlToCheck.value = Number(enteredNum).toLocaleString();
}
<h5>Monthly Spend</h5>
<div >
<div >
<div >
<input type="text" id="jan" aria-placeholder="January" placeholder="0.00">
<label for="jan">January<br>$</label>
</div>
<div >
<input type="text" id="feb" aria-placeholder="February" placeholder="0.00">
<label for="feb">February<br>$</label>
</div>
<div >
<input type="text" id="mar" aria-placeholder="March" placeholder="0.00">
<label for="mar">March<br>$</label>
</div>
<div >
<input type="text" id="apr" aria-placeholder="April" placeholder="0.00">
<label for="apr">April<br>$</label>
</div>
<div >
<input type="text" id="may" aria-placeholder="May" placeholder="0.00">
<label for="may">May<br>$</label>
</div>
<div >
<input type="text" id="jun" aria-placeholder="June" placeholder="0.00">
<label for="jun">June<br>$</label>
</div>
</div>
<div >
<div >
<input type="text" id="jul" aria-placeholder="July" placeholder="0.00">
<label for="jul">July<br>$</label>
</div>
<div >
<input type="text" id="aug" aria-placeholder="August" placeholder="0.00">
<label for="aug">August<br>$</label>
</div>
<div >
<input type="text" id="sep" aria-placeholder="September" placeholder="0.00">
<label for="sep">September<br>$</label>
</div>
<div >
<input type="text" id="oct" aria-placeholder="October" placeholder="$0.00">
<label for="oct">October<br>$</label>
</div>
<div >
<input type="text" id="nov" aria-placeholder="November" placeholder="0.00">
<label for="nov">November<br>$</label>
</div>
<div >
<input type="text" id="dec" aria-placeholder="December" placeholder="0.00">
<label for="dec">December<br>$</label>
</div>
</div>
<div >
<div >
<h3>Total: $<output type="number" id="total"></output></h3>
</div>