简体   繁体   English

如何使用Javascript从输入值中获得总和?

[英]How to get total sum from input values with Javascript?

I am fairly new to Javascript, and working with the DOM. 我对Javascript很新,并且使用DOM。 I'm trying to add the user's input values to a total. 我正在尝试将用户的输入值添加到总计。 Every time they add a value for credit or debit, it will add it to the total. 每次他们为信用卡或借记卡添加一个值时,它都会将其添加到总额中。 Every attempt I've made, results in NaN, undefined or some other error. 我所做的每一次尝试都会导致NaN,未定义或其他错误。 Do I need a for loop or is there a simpler way to do this? 我是否需要for循环或者有更简单的方法吗?

Here is the full code: JSFiddle 这是完整的代码: JSFiddle

My Javascript snippet (to add totals): 我的Javascript代码段(添加总计):

if (document.getElementsByTagName('select')[0].selectedIndex == 1) {
transactions.appendChild(debit);
text = document.createTextNode("debit");
td2.appendChild(text);

var money = document.querySelector('input[type="number"]').value;
money = parseFloat(money).toFixed(2);
var total = 0;

for (var i = 0; i < money.length; i++) {
  if (parseInt(money[i].value))
    total += parseInt(money[i].value);
}

document.querySelector('.right > .total.debits').innerHTML = total;

evt.target.reset();

} }

My HTML: 我的HTML:

<body>
<section class="wrapper">
    <h1>Transaction Tracker</h1>
    <form class="transaction-frm">
        <fieldset>
            <legend>Add Transaction</legend>
            <div class="frm-group">
                <input class="frm-control" type="text" name="description" size="30" placeholder="description" />
            </div>
            <div class="frm-group">
                <select class="frm-control" name="type">
                    <option value="">type</option>
                    <option value="debit">debit</option>
                    <option value="credit">credit</option>
                </select>
            </div>
            <div class="frm-group">
                <i class="edit fa fa-dollar"></i>
                <input class="frm-control" type="number" name="currency" min="0" max="9999" step="0.01" size="4" placeholder="0.00" />
            </div>
            <div class="frm-group">
                <input class="frm-control" type="submit" value="add" />
            </div>
            <div class="error"></div>
        </fieldset>
    </form>


    <h2>Transactions</h2>


    <table class="transactions">
        <thead>
            <tr>
                <td colspan="4" class="right">
                    Total debits: <span class="total debits">$0.00</span>
                    Total credits: <span class="total credits">$0.00</span>
                </td>
            </tr>
            <tr>
                <th>Description</th>
                <th>Type</th>
                <th class="amount">Amount</th>
                <th class="tools">Tools</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
</section>
<script src="js/main.js"></script>

This should work if you replace your current JSFiddle script with this. 如果用这个替换当前的JSFiddle脚本,这应该有效。 It takes the current value in the span and removes the $ then adds to it. 它获取跨度中的当前值并删除$然后添加到它。 Then to make it look nice it makes it a fixed length after the decimal and prepends a dollar sign. 然后为了使它看起来不错,它使它在小数点后固定长度并且在前面加上一个美元符号。 And finally updates the span value to the new total. 最后将跨度值更新为新总量。 This will need modification if you plan to be able to delete nodes. 如果您计划能够删除节点,则需要进行修改。 If you did implement deleting you would read the node type and value and minus instead of add. 如果您确实实现了删除,则会读取节点类型和值以及减去而不是添加。

document.querySelector('form').addEventListener('submit', function(evt) {

  var transactions = document.querySelector('tbody');
  var debit, credit, moneyText, descriptionText,
    error, td, td2, td3, td4, td5, td6, td7, td8, i, i2;

  description = document.querySelector('input[type="text"]').value;
      money = document.querySelector('input[type="number"]').value;
      money = parseFloat(money).toFixed(2);


  if (document.getElementsByTagName('select')[0].selectedIndex == 0) {
    alert("Please select a payment option");
    document.getElementsByTagName('select')[0].focus();
  }
  if (document.querySelector('input[type="text"]').value == "") {
    alert("Please enter a description");
    document.querySelector('input[type="text"]').focus();
  }

  if (document.querySelector('input[type="number"]').value < 0 || document.querySelector('input[type="number"]').value == "") {
    alert("Please enter a number over 0");
    document.querySelector('input[type="number"]').focus();
  }

  debit = document.createElement('tr');
  credit = document.createElement('tr');
  debitDescriptionText = document.createTextNode(description);
  debitMoneyText = document.createTextNode(money);
  creditDescriptionText = document.createTextNode(description);
  creditMoneyText = document.createTextNode(money);

  td = document.createElement('td');
  td2 = document.createElement('td');
  td3 = document.createElement('td');
  td4 = document.createElement('td');

  td5 = document.createElement('td');
  td6 = document.createElement('td');
  td7 = document.createElement('td');
  td8 = document.createElement('td');

  i = document.createElement('i');
  i2 = document.createElement('i');

  debit.setAttribute('class', 'debit');
  credit.setAttribute('class', 'credit');
  td3.setAttribute('class', 'amount');
  td4.setAttribute('class', 'tools');
  td7.setAttribute('class', 'amount');
  td8.setAttribute('class', 'tools');

  i.setAttribute('class', 'delete fa fa-trash-o');
  i2.setAttribute('class', 'delete fa fa-trash-o');

  sign = document.createTextNode("$");
  td3.appendChild(sign);

  sign = document.createTextNode("$");
  td7.appendChild(sign);

  debit.appendChild(td);
  debit.appendChild(td2);
  debit.appendChild(td3);
  debit.appendChild(td4);
  td.appendChild(debitDescriptionText);
  td3.appendChild(debitMoneyText);
  td5.appendChild(creditDescriptionText);
  td7.appendChild(creditMoneyText);

  td4.appendChild(i);
  credit.appendChild(td5);
  credit.appendChild(td6);
  credit.appendChild(td7);
  credit.appendChild(td8);
  td8.appendChild(i2);


  if (document.getElementsByTagName('select')[0].selectedIndex == 1) {
    transactions.appendChild(debit);
    text = document.createTextNode("debit");
    td2.appendChild(text);

    var money = document.querySelector('input[type="number"]').value;


    document.querySelector('.right > .total.debits').innerHTML ="$"+(parseInt(document.querySelector('.right > .total.debits').innerText.replace("$",""))+parseFloat(money)).toFixed(2);

    evt.target.reset();
  }

  if (document.getElementsByTagName('select')[0].selectedIndex == 2) {
    transactions.appendChild(credit);
    text = document.createTextNode("credit");
    td6.appendChild(text);

    var money = document.querySelector('input[type="number"]').value;


    document.querySelector('.right > .total.credits').innerHTML ="$"+(parseInt(document.querySelector('.right > .total.credits').innerText.replace("$",""))+parseFloat(money)).toFixed(2);


    evt.target.reset();
  }

  evt.preventDefault();

});

document.querySelector('.transactions').addEventListener('click', function(evt) {
  // check for click on an arrow
  var target = evt.target.parentNode;
  var trash = target.parentNode;

  if (evt.target.classList.contains('delete')) {
    trash.remove(target);
  }
});

You need to declare total variables outside of your event. 您需要在事件之外声明总变量。

`var debitTotal = 0.0, creditTotal = 0.0;`

you are also converting too many times when trying to get the total it's unnecessary, you can just add floats. 当你试图获得总数时,你也会转换太多次,你可以添加花车。 Remove the .toFixed(2) from money = parseFloat(money).toFixed(2) . 卸下.toFixed(2)money = parseFloat(money).toFixed(2) toFixed(2) turns your value into a string. toFixed(2)将您的值转换为字符串。 Also remove the for loop . 同时删除for loop All you need is: 所有你需要的是:

var money = document.querySelector('input[type="number"]').value;
money = parseFloat(money);
debitTotal += money;

to get your total. 得到你的总数。 Then to display the total you can add .toFixed(2); 然后显示你可以添加的总数.toFixed(2);

document.querySelector('.right > .total.debits').innerHTML = '$' + debitTotal.toFixed(2);

I did basically the same thing for credits. 对于学分,我做了基本相同的事情。

Here is the updated jsfiddle . 这是更新的jsfiddle

I checked the fiddle you made, and the transactions listing doesn't seem to throw any errors as long as the form field are filled properly. 我检查了你做的小提琴,只要表格字段填写正确,交易清单似乎没有任何错误。

The validation checks you added to the fields need a return statement after it resolves as invalid. 您添加到字段的验证检查在解析为无效后需要返回语句。

The problem is if no data is entered, the value is being resolved as NaN and you are adding adding a row for it even after displaying the alert saying it is invalid. 问题是如果没有输入数据,则该值将被解析为NaN,并且即使在显示警告声明它无效之后,您也要添加一行。 (Since the function does not exit even if input values are invalid) (因为即使输入值无效,函数也不会退出)

money = parseFloat(money).toFixed(2);

typeof money -> number with 2 characters after the decimal point typeof money - >小数点后2个字符的数字

var total = 0;

for (var i = 0; i < money.length; i++) {

money becomes string and you check every character 钱成为字符串,你检查每个字符

  if (parseInt(money[i].value))

money[i](string variable).value is undefined, so parseInt(undefined) = NaN -means Not a Number money [i](字符串变量).value是未定义的,所以parseInt(undefined)= NaN -means不是数字

    total += parseInt(money[i].value);
}

so you don' need loop, just 所以你不需要循环,只是

total += parseInt(money)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM