Я пишу JavaScript в Google Apps, который будет записывать ежемесячные доллары в электронную таблицу из пользовательского ввода HTML.
Он функционирует там, где он принимает ввод от пользователя через ввод html. Затем я использую класс, который захватывает и вычисляет, когда пользователь вводит контент, который активно пишет на экране.
Он должен принимать положительные и отрицательные числа. Хотя он принимает ввод пользователя, он отображает число только как положительное значение, даже если оно отрицательное. Кроме того, он не правильно считает. Я заметил, что если в числе стоит запятая, например 1000, то все после запятой отбрасывается. Я делюсь ниже сценарием заголовка, а затем сценарием в теле HTML-файла, а также html-кодом с функцией. Наконец, я использую Bootstrap, который отлично подходит для других областей кода.
Головной сценарий
<script>
function toFinalNumberFormat(controlToCheck) {
var enteredNum = '' + controlToCheck.value;
enteredNum = enteredNum.replace(/[^0-9\.]+/g, '');
controlToCheck.value = Number(enteredNum).toLocaleString();
}
</script>Скрипт в теле HTML
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, '$&,');
} Это фрагмент HTML
<h5>Monthly Spend</h5>
<div class = "container3">
<div class = "row">
<div class = "form-floating col-sm-2">
<input type = "text" id = "jan" class = "form-control input-group add-input" aria-placeholder = "January" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "jan">January<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "feb" class = "form-control input-group add-input" aria-placeholder = "February" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "feb">February<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "mar" class = "form-control input-group add-input" aria-placeholder = "March" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "mar">March<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "apr" class = "form-control input-group add-input" aria-placeholder = "April" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "apr">April<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "may" class = "form-control input-group add-input" aria-placeholder = "May" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "may">May<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "jun" class = "form-control input-group add-input" aria-placeholder = "June" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "jun">June<br>$</label>
</div>
</div>
<div class = "row">
<div class = "form-floating col-sm-2">
<input type = "text" id = "jul" class = "form-control input-group add-input" aria-placeholder = "July" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "jul">July<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "aug" class = "form-control input-group add-input" aria-placeholder = "August" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "aug">August<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "sep" class = "form-control input-group add-input" aria-placeholder = "September" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "sep">September<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "oct" class = "form-control input-group add-input" aria-placeholder = "October" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "$0.00">
<label for = "oct">October<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "nov" class = "form-control input-group add-input" aria-placeholder = "November" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "nov">November<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "dec" class = "form-control input-group add-input" aria-placeholder = "December" onblur = "toFinalNumberFormat(this);" oninput = "sumTotal()" placeholder = "0.00">
<label for = "dec">December<br>$</label>
</div>
</div>
<div class = "row">
<div class = "form-floating col-sm-4">
<h3>Total: $<output type = "number" id = "total"></output></h3>
</div>
Может кто-нибудь указать, что не так с кодом? Спасибо!
Вы вызываете toFinalNumberFormat() только тогда, когда пользователь покидает поле, но вы вызываете sumTotal(), когда он печатает. Вам нужно убрать запятые в sumTotal().
@Barmar Хорошо, мне нужен 'parseFloat()', потому что пользователи будут вводить значения, содержащие десятичные числа, поскольку они не обязательно всегда являются целыми числами.
Вам нужно использовать parseFloat(inputs[i].value.replace(/[^0-9]+/g, ''))
Вы удаляете . в своем регулярном выражении, вы не должны этого делать.
Извините, не могли бы вы уточнить, я новичок в javascript. Я обновил код, чтобы он читался так, как вы делали выше, но теперь он вообще не вычисляется. Я получаю значение NaN в поле, отображающем экран. Позвольте мне обновить мой вопрос, чтобы показать полный html, я понял, что пропустил поле вывода.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


document.getElementsByClassName() возвращает список элементов, вам нужно перебрать его, чтобы добавить все прослушиватели событий.
Вам нужно удалить запятые, вызывающие parseFloat() для каждого значения в цикле, а не после вычисления суммы, потому что parseFloat() не может анализировать числа с разделителями-запятыми.
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 class = "container3">
<div class = "row">
<div class = "form-floating col-sm-2">
<input type = "text" id = "jan" class = "form-control input-group add-input" aria-placeholder = "January" placeholder = "0.00">
<label for = "jan">January<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "feb" class = "form-control input-group add-input" aria-placeholder = "February" placeholder = "0.00">
<label for = "feb">February<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "mar" class = "form-control input-group add-input" aria-placeholder = "March" placeholder = "0.00">
<label for = "mar">March<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "apr" class = "form-control input-group add-input" aria-placeholder = "April" placeholder = "0.00">
<label for = "apr">April<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "may" class = "form-control input-group add-input" aria-placeholder = "May" placeholder = "0.00">
<label for = "may">May<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "jun" class = "form-control input-group add-input" aria-placeholder = "June" placeholder = "0.00">
<label for = "jun">June<br>$</label>
</div>
</div>
<div class = "row">
<div class = "form-floating col-sm-2">
<input type = "text" id = "jul" class = "form-control input-group add-input" aria-placeholder = "July" placeholder = "0.00">
<label for = "jul">July<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "aug" class = "form-control input-group add-input" aria-placeholder = "August" placeholder = "0.00">
<label for = "aug">August<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "sep" class = "form-control input-group add-input" aria-placeholder = "September" placeholder = "0.00">
<label for = "sep">September<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "oct" class = "form-control input-group add-input" aria-placeholder = "October" placeholder = "$0.00">
<label for = "oct">October<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "nov" class = "form-control input-group add-input" aria-placeholder = "November" placeholder = "0.00">
<label for = "nov">November<br>$</label>
</div>
<div class = "form-floating col-sm-2">
<input type = "text" id = "dec" class = "form-control input-group add-input" aria-placeholder = "December" placeholder = "0.00">
<label for = "dec">December<br>$</label>
</div>
</div>
<div class = "row">
<div class = "form-floating col-sm-4">
<h3>Total: $<output type = "number" id = "total"></output></h3>
</div>Хотели бы вы проверить totalSum перед записью на вход? Я не понимаю приведенное выше требование: ... оно отображает число только как положительное количество, даже если оно отрицательное, но это позволит исправить отрицательные числа? Возможно, ОП хочет, чтобы они были заключены в скобки, как отрицательные числа в счете?
Если пользователь вводит отрицательное число, - будет удален вызовом replace(), поэтому результат никогда не может быть отрицательным.
@Barmar Что интересно, так это то, что код работает, но общее количество не показывает добавление, пока все 12 полей не будут заполнены, тогда он покажет общее количество. Я обновил ввод html и добавил значение = "0", но это не работает. Также мне нужно, чтобы каждый ввод показывал -5000, а также вычитал это из общего количества. Поэтому, если я введу -5000 в поле января, моя сумма должна начинаться с -5000. Мне нужно разрешить пользователю вводить -5000. Большое спасибо за Вашу помощь.
Измените регулярное выражение на /[^-\d.]/g, чтобы разрешить использование отрицательных чисел.
Я забыл второй аргумент replace(), я исправил его.
@Barmar Я обновил регулярное выражение и включил - и оно позволяет пользователю вводить, но как только вы покидаете поле, оно преобразует его в положительное и делает то же самое с общей суммой
Вам нужно исправить регулярное выражение в toFinalNumberFormat() так же, как я исправил его здесь.
@Barmar Я обновил в обоих местах, и хотя он позволяет мне вводить отрицательное число, он преобразует его в положительное, а итог распознает только положительное число.
Я поместил полное решение в свой ответ. Это работает правильно.
@Бармар, спасибо! Оно работает! Я собираюсь сравнить то, что вы дали мне, с тем, что я сделал, чтобы я мог учиться. Большое спасибо!
К вашему сведению,
parseFloat()принимает только один аргумент. Аргумент системы счисления доступен только вparseInt()(и по умолчанию он равен 10, поэтому обычно он не нужен).