简体   繁体   English

使用运行总计时,Javascript $ NaN

[英]Javascript $NaN when working with running total

I have this Javascript function that calculates up to 30 different fields as the user can add up to 30 items they sold and input the amount and have the price show up. 我有这个Javascript函数,可以计算多达30个不同的字段,因为用户可以添加最多30个他们销售的商品并输入金额并显示价格。 This code works for each line item, I can add up to 30 items and see their individual totals just fine. 此代码适用于每个订单项,我最多可以添加30个项目并查看其各自的总计。 At the bottom of the form I have a subtotal area and that's where I can't shake this $NaN showing up... when viewing the code its the subtotal, stantot, and showtot variables I'm getting NaN for... 在表格的底部我有一个小计区域,这是我无法动摇这个$ NaN出现的地方...当查看代码时,我得到了NaN的小计,stantot和showtot变量......

$(document).ready(function() {
    var subtotal = 0;
    var stantot = 0;
    var showtot = 0;
    $("input").keyup(function() {
        for (i = 0; i <= 30; i++) {
            var unitp = $("#unitp" + i).val();
            var casep = $("#casep" + i).val();
            var units = $("#units" + i).val();
            var cases = $("#cases" + i).val();
            var st_disc = $("#st_disc").val();
            var sh_disc = $("#sh_disc").val();

            var unitr = (unitp * units);
            var caser = (casep * cases);
            var result = (unitr + caser);
            var st_disc_fix = (st_disc / 100);
            var sh_disc_fix = (sh_disc / 100);
            var st_disc_solo = (st_disc_fix * result);
            var sh_disc_solo = (sh_disc_fix * result);
            var disc_total = (st_disc_fix + sh_disc_fix);
            var disc_whole = (disc_total * result);

            var disc = (result - disc_whole);
            var st_disc_tot = (result - disc_whole);
            var sh_disc_tot = (result - disc_whole);

            $("#line" + i).val('$' + result.toFixed(2));
            $("#disc" + i).val('$' + disc.toFixed(2));
            subtotal += parseInt(result);
            stantot += parseInt(st_disc_tot);
            showtot += parseInt(sh_disc_tot);
        }
        $("#totretail").val('$' + subtotal.toFixed(2));
        $("#standiscount").val('$' + stantot.toFixed(2));
        $("#showdiscount").val('$' + showtot.toFixed(2));

        var totship = ($("#totship").val() * 1);
        var tottax = ($("#tottax").val() * 1);

        var finaltotal = (subtotal + stantot + showtot + totship + tottax);
        $("#total").val('$' + finaltotal.toFixed(2));

    });
});

Here's what I would do. 这就是我要做的。

First, I would create a function that takes a string and guarantees that a number is returned: 首先,我将创建一个带字符串的函数,并保证返回一个数字:

function toNumber(val) {
    var num = parseFloat(val);
    num = isNaN(num) ? 0 : num;
    return num;
}

In this case, any NaN values are converted to zero. 在这种情况下,任何NaN值都将转换为零。 You can alter this to suit the needs of your application. 您可以更改此选项以满足您的应用程序的需要。

Then, I would update your variable declarations where you're pulling in the field values like so: 然后,我会更新你的变量声明,你可以在这里输入字段值,如下所示:

var unitp = toNumber($("#unitp" + i).val());
var casep = toNumber($("#casep" + i).val());
var units = toNumber($("#units" + i).val());
var cases = toNumber($("#cases" + i).val());
var st_disc = toNumber($("#st_disc").val());
var sh_disc = toNumber($("#sh_disc").val());

Since all proceeding calculations are based on these variables, if you guarantee that none of these are NaN , then none of the following values will be NaN either (barring exceptional circumstances). 由于所有的出发计算都是基于这些变量,如果你保证, 这些都不是NaN ,那么没有下列值将是NaN是(除非特殊情况)。

Saint Gerbil's answer worked beautifully, here is my working code for any future reference... Saint Gerbil的答案非常精彩,这是我未来参考的工作代码......

$(document).ready(function() {
var subtotal = 0;
var stantot = 0;
var showtot = 0;
$("input").keyup(function() {
    for (var i = 0; i <= 30; i++) {
        var unitp = parseFloat($("#unitp" + i).val()) || 0;
        var casep = parseFloat($("#casep" + i).val()) || 0;
        var units = parseFloat($("#units" + i).val()) || 0;
        var cases = parseFloat($("#cases" + i).val()) || 0;
        var st_disc = parseFloat($("#st_disc").val()) || 0;
        var sh_disc = parseFloat($("#sh_disc").val()) || 0;

        var unitr = (unitp * units);
        var caser = (casep * cases);
        var result = (unitr + caser);
        var st_disc_fix = (st_disc / 100);
        var sh_disc_fix = (sh_disc / 100);
        var st_disc_solo = (st_disc_fix * result);
        var sh_disc_solo = (sh_disc_fix * result);
        var disc_total = (st_disc_fix + sh_disc_fix);
        var disc_whole = (disc_total * result);

        var disc = (result - disc_whole);
        var st_disc_tot = (result - disc_whole);
        var sh_disc_tot = (result - disc_whole);

        $("#line" + i).val(result.toFixed(2));
        $("#disc" + i).val(disc.toFixed(2));
        subtotal += parseFloat((unitp * units) + (casep * cases));
        stantot += parseFloat(st_disc_tot);
        showtot += parseFloat(sh_disc_tot);
    }
    $("#totretail").val(subtotal.toFixed(2));
    $("#standiscount").val(stantot.toFixed(2));
    $("#showdiscount").val(showtot.toFixed(2));

    var totship = ($("#totship").val() * 1);
    var tottax = ($("#tottax").val() * 1);

    var finaltotal = (subtotal + stantot + showtot + totship + tottax);
    $("#total").val(finaltotal.toFixed(2));

    });
}); 

change 更改

for (i = 0; i <= 30; i++) {

to

for (var i = 0; i <= 30; i++) {

you should check for empty and null strings so change all the statements like this 你应该检查空字符串和空字符串,所以更改所有这样的语句

var unitp = $("#unitp" + i).val();

to

var unitp = $("#unitp" + i).val()===''?0:$("#unitp" + i).val();

OR 要么

var unitp = $("#unitp" + i).val()||0;

Pass all of your user input to parseFloat or parseInt (depending if you need decimal points) 将所有用户输入传递给parseFloat或parseInt(取决于您是否需要小数点)

$(document).ready(function() {
    var subtotal = 0;
    var stantot = 0;
    var showtot = 0;
    $("input").keyup(function() {
        for (var i = 0; i <= 30; i++) {
            var unitp = parseFloat($("#unitp" + i).val()) || 0;
            var casep = parseFloat($("#casep" + i).val()) || 0;
            var units = parseInt($("#units" + i).val(),10) || 0;
            var cases = parseInt($("#cases" + i).val(),10) || 0;
            var st_disc = parseFloat($("#st_disc").val()) || 0;
            var sh_disc = parseFloat($("#sh_disc").val()) || 0;

            var unitr = (unitp * units);
            var caser = (casep * cases);
            var result = (unitr + caser);
            var st_disc_fix = (st_disc / 100);
            var sh_disc_fix = (sh_disc / 100);
            var st_disc_solo = (st_disc_fix * result);
            var sh_disc_solo = (sh_disc_fix * result);
            var disc_total = (st_disc_fix + sh_disc_fix);
            var disc_whole = (disc_total * result);

            var disc = (result - disc_whole);
            var st_disc_tot = (result - disc_whole);
            var sh_disc_tot = (result - disc_whole);

            $("#line" + i).val('$' + result.toFixed(2));
            $("#disc" + i).val('$' + disc.toFixed(2));
            subtotal += parseInt(result);
            stantot += parseInt(st_disc_tot);
            showtot += parseInt(sh_disc_tot);
        }
        $("#totretail").val('$' + subtotal.toFixed(2));
        $("#standiscount").val('$' + stantot.toFixed(2));
        $("#showdiscount").val('$' + showtot.toFixed(2));

        var totship = ($("#totship").val() * 1);
        var tottax = ($("#tottax").val() * 1);

        var finaltotal = (subtotal + stantot + showtot + totship + tottax);
        $("#total").val('$' + finaltotal.toFixed(2));

    });
});

This will default NaN entries to 0 and should carry on as you expect. 这将默认NaN条目为0并且应该按预期继续。

not sure what values you are expecting ints or floats so swap as needed. 不确定你期望什么值的int或浮点数,所以根据需要交换。

EDIT: Added a couple of parseInt's so you know how to call them. 编辑:添加了几个parseInt,所以你知道如何调用它们。

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

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