JavaScript:格式化输入方法会给出错误的值

JavaScript: formatting input method gives wrong values

本文关键字:出错 错误 格式化 输入 方法 JavaScript      更新时间:2024-06-04

我正在JavaScript/JQuery中编程一个方法,该方法转换用户在输入框中输入的值。其意义在于使该输入具有区域意识。该功能包括删除开头的零,放置千个分隔符和一个十进制分隔符。

在这个用例中,是符号、千位分隔符和点十进制分隔符

例如,以下输入转换为以下输出。

  • 12300=>12300.00
  • 100=>100.00
  • 1023.456=>1023.456

现在数字仍然存在问题,不到100。例如,以下输入格式错误:

  • 1=>1.00
  • 2.05=>.05
  • 20=>20,.00
  • 25.65=>.65

当我没有在输入框中输入十进制值时,我会得到一个不需要的千分隔符。当我输入十进制值时,我会丢失十进制分隔符之前的内容。

代码:

$("#queryInstructedAmountFrom").change(function(){
                        var amount = $("#queryInstructedAmountFrom").val();
                        amount = removeZeros(amount);
                        var nonFractions = amount.match(/.{1,3}/g);
                        if(nonFractions == null) {
                            nonFractions = [];
                            nonFractions.push(amount);
                        }
                        var splittedValues = amount.split(/[,.]/);
                        amount = "";
                        if(splittedValues.length == 1) {
                            amount += splittedValues[0];
                            nonFractions = amount.match(/.{1,3}/g);
                            var firstIndex = amount.length % 3;
                            if(firstIndex != 0) {
                            var firstNumbers = amount.substr(0, firstIndex);
                            amount = amount.substr(firstIndex);
                            nonFractions = amount.match(/.{1,3}/g);
                            if(nonFractions == null) {
                                nonFractions = [];
                                nonFractions.push(amount);
                            }
                            amount = "";
                            amount += firstNumbers;
                            amount += thousandSeparator;
                            } else {
                                amount = "";
                            }

                            for(var i=0 ; i < nonFractions.length ; i++) {
                                amount += nonFractions[i];
                                if(i < (nonFractions.length - 1) && nonFractions.length != 1){
                                    amount += thousandSeparator;
                                }
                            }
                            amount += decimalSeparator;
                            amount += "00";
                        } else {
                            for(var i=0 ; i < splittedValues.length - 1 ; i++) {
                                amount += splittedValues[i];
                            }
                            nonFractions = amount.match(/.{1,3}/g);
                            var firstIndex = amount.length % 3;
                            if(firstIndex == 0) {
                                nonFractions = amount.match(/.{1,3}/g);
                            }
                            if(firstIndex >= 1 && nonFractions != null) {
                                var firstNumbers = amount.substr(0, firstIndex);
                                amount = amount.substr(firstIndex);
                                nonFractions = amount.match(/.{1,3}/g);
                                if(nonFractions != null) {
                                    amount = "";
                                    amount += firstNumbers;
                                    amount += thousandSeparator;
                                } else {
                                    nonFractions = [];
                                    nonFractions.push(amount);
                                }
                            } else {
                                amount = "";
                            }

                            for(var i=0 ; i < nonFractions.length ; i++) {
                                amount += nonFractions[i];
                                if(i < (nonFractions.length - 1) && nonFractions.length != 1){
                                    amount += thousandSeparator;
                                }
                            }
                            amount += decimalSeparator;
                            amount += splittedValues[splittedValues.length -1];
                        }
        $("#queryInstructedAmountFrom").val(amount);
      });
    });
function removeZeros(amount) {
            while (amount.charAt(0) === '0') {
                amount = amount.substr(1);
           }
           if(amount.length == 0){
            amount = "0";
           }
            return amount;
        }

出了什么问题?

出了什么问题?

我几乎什么都会说。你有非常不清楚、混乱的代码,我几乎没有遵循你的逻辑,但你在代码中有几个关键的逻辑错误,例如:

1

1被转换为1.00,因为:

var splittedValues = amount.split(/[,.]/);

创建具有单个元素['1']的数组

var firstIndex = amount.length % 3;

1%3==1,所以您将进入if条件,其中amount += thousandSeparator;附加了千个分隔符,但只有在之后才应该添加分隔符

2

2.05是错误的,因为它进入了这个分支:

var firstNumbers = amount.substr(0, firstIndex); // stores '2' into firstNumbers
amount = amount.substr(firstIndex); // sets amount to empty string

稍后,nonFractions为空:

nonFractions = [];
nonFractions.push(amount);

但是firstNumbers根本没用(它的值丢失了)

3

还有:

    nonFractions = amount.match(/.{1,3}/g);
    var firstIndex = amount.length % 3;
    if (firstIndex == 0) {
        nonFractions = amount.match(/.{1,3}/g);
    }

nonFractions重新初始化的意义是什么?

可能有更多的错误和边缘情况下,这个代码失败了,我建议你使用库(就像在其他答案中一样),或者如果你想拥有自己的代码,这里是你可以使用的简单版本:

$(document).ready(function() {
    $("#queryInstructedAmountFrom").change(function() {
        var val = parseFloat(('0' + $("#queryInstructedAmountFrom").val()).replace(/,/g, '')); // convert original text value into float
        val = ('' + (Math.round(val * 100.0) / 100.0)).split('.', 2);
        if (val.length < 2) val[1] = '00'; // handle fractional part
        else while (val[1].length < 2) val[1] += '0';
        var t = 0;
        while ((val[0].length - t) > 3) { // append thousand separators
            val[0] = val[0].substr(0, val[0].length - t - 3) + ',' + val[0].substr(val[0].length - t - 3);
            t += 4;
        }
        $("#queryInstructedAmountFrom").val(val[0] + '.' + val[1]);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="queryInstructedAmountFrom">

为什么不使用jQuery Mask插件?

<input type="text" id="money" />

只需调用插件:

$('#money').mask('000.000.000.000.000,00', {reverse: true});

Plunker:https://plnkr.co/edit/PY7ihpS3Amtzeya9c6KN?p=preview

请参阅下面更新的代码。

$(document).ready(function() {
    $("#queryInstructedAmountFrom").change(function() {
        var amount = $("#queryInstructedAmountFrom").val();
        amount = removeZeros(amount);
        
        // format amount using 'ThousandFormattedValue' function
        amount = ThousandFormattedValue(amount);
        $("#queryInstructedAmountFrom").val(amount);
    });
});
function removeZeros(amount) {
    while (amount.charAt(0) === '0') {
        amount = amount.substr(1);
    }
    if (amount.length == 0) {
        amount = "0";
    }
    return amount;
}
function ThousandFormattedValue(iValue) {
    // declaring variables and initializing the values
    var numberArray, integerPart, reversedInteger, IntegerConstruction = "",
        lengthOfInteger, iStart = 0;
    // splitting number at decimal point by converting the number to string
    numberArray = iValue.toString().split(".");
    // get the integer part
    integerPart = numberArray[0];
    // get the length of the number
    lengthOfInteger = integerPart.length;
    // if no decimal part is present then add 00 after decimal point
    if (numberArray[1] === undefined) {
        numberArray.push("00");
    }
    /* split the integer part of number to individual digits and reverse the number
        ["4" , "3" , "2" , "1"] - after split
        ["1" , "2" , "3" , "4"] - after reverse
        "1234" - after join     
    */
    reversedInteger = integerPart.split("").reverse().join("");
    // loop through the string to add commas in between
    while (iStart + 3 < lengthOfInteger) {
        // get substring of very 3 digits and add "," at the end
        IntegerConstruction += (reversedInteger.substr(iStart, 3) + ",");
        // increase counter for next 3 digits
        iStart += 3;
    }
    // after adding the commas add the remaining digits 
    IntegerConstruction += reversedInteger.substr(iStart, 3);
    /* now split the constructed string and reverse the array followed by joining to get the formatted number
        ["1" , "2" , "3" , "," ,"4"] - after split
        ["4" , "," , "3" , "2" , "1"] - after reverse
        "4,321" - after join
    */
    numberArray[0] = IntegerConstruction.split("").reverse().join("");
    // return the string as Integer part concatinated with decimal part
    return numberArray.join(".");
}

相关文章: