Код Javascript неправильно суммирует число с использованием Google Apps с HTML

Я пишу 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>

Может кто-нибудь указать, что не так с кодом? Спасибо!

К вашему сведению, parseFloat() принимает только один аргумент. Аргумент системы счисления доступен только в parseInt() (и по умолчанию он равен 10, поэтому обычно он не нужен).

Barmar 01.02.2023 19:00

Вы вызываете toFinalNumberFormat() только тогда, когда пользователь покидает поле, но вы вызываете sumTotal(), когда он печатает. Вам нужно убрать запятые в sumTotal().

Barmar 01.02.2023 19:03

@Barmar Хорошо, мне нужен 'parseFloat()', потому что пользователи будут вводить значения, содержащие десятичные числа, поскольку они не обязательно всегда являются целыми числами.

Berryblue 01.02.2023 19:07

Вам нужно использовать parseFloat(inputs[i].value.replace(/[^0-9]+/g, ''))

Barmar 01.02.2023 19:14

Вы удаляете . в своем регулярном выражении, вы не должны этого делать.

Barmar 01.02.2023 19:14

Извините, не могли бы вы уточнить, я новичок в javascript. Я обновил код, чтобы он читался так, как вы делали выше, но теперь он вообще не вычисляется. Я получаю значение NaN в поле, отображающем экран. Позвольте мне обновить мой вопрос, чтобы показать полный html, я понял, что пропустил поле вывода.

Berryblue 01.02.2023 19:22
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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 перед записью на вход? Я не понимаю приведенное выше требование: ... оно отображает число только как положительное количество, даже если оно отрицательное, но это позволит исправить отрицательные числа? Возможно, ОП хочет, чтобы они были заключены в скобки, как отрицательные числа в счете?

War10ck 01.02.2023 20:58

Если пользователь вводит отрицательное число, - будет удален вызовом replace(), поэтому результат никогда не может быть отрицательным.

Barmar 01.02.2023 20:59

@Barmar Что интересно, так это то, что код работает, но общее количество не показывает добавление, пока все 12 полей не будут заполнены, тогда он покажет общее количество. Я обновил ввод html и добавил значение = "0", но это не работает. Также мне нужно, чтобы каждый ввод показывал -5000, а также вычитал это из общего количества. Поэтому, если я введу -5000 в поле января, моя сумма должна начинаться с -5000. Мне нужно разрешить пользователю вводить -5000. Большое спасибо за Вашу помощь.

Berryblue 01.02.2023 21:47

Измените регулярное выражение на /[^-\d.]/g, чтобы разрешить использование отрицательных чисел.

Barmar 01.02.2023 21:48

Я забыл второй аргумент replace(), я исправил его.

Barmar 01.02.2023 21:48

@Barmar Я обновил регулярное выражение и включил - и оно позволяет пользователю вводить, но как только вы покидаете поле, оно преобразует его в положительное и делает то же самое с общей суммой

Berryblue 01.02.2023 21:52

Вам нужно исправить регулярное выражение в toFinalNumberFormat() так же, как я исправил его здесь.

Barmar 01.02.2023 21:54

@Barmar Я обновил в обоих местах, и хотя он позволяет мне вводить отрицательное число, он преобразует его в положительное, а итог распознает только положительное число.

Berryblue 01.02.2023 21:57

Я поместил полное решение в свой ответ. Это работает правильно.

Barmar 01.02.2023 22:00

@Бармар, спасибо! Оно работает! Я собираюсь сравнить то, что вы дали мне, с тем, что я сделал, чтобы я мог учиться. Большое спасибо!

Berryblue 01.02.2023 22:12

Другие вопросы по теме