即使用户输入foo.nnn.nnbar,javascript中的两位十进制精度

时间:2014-01-27 19:00:57

标签: javascript html

这似乎是一个很好的一般问题,已被问到并解决了一百万次。事实上,我确信我在几年前就已经完成了这项工作,但很久以前就失去了它。给定一个基本的HTML(或xhtml)输入元素,例如:

,问题很简单
<input name="some_num" type="text" id="some_num" 
       size="10" maxlength="10" value="0" 
       class="num_align_right" 
       title="decimal number with two digits right of the decimal point" >

现在实际上用户可以输入“barfoo”或“aj2.34t”或甚至“$ 2,345.67”。我真正想要的是从输入的任何字符串中提取数字,一次一个,从左到右并记下小数点(如果有的话)。如果没有十进制字符0到9 ascii那么该字段中的值被视为0.00。否则我相信你明白了。

所以我做的第一件事是想出一种方法来检测一个非数字并处理它:

    function noNaN (a) {
        return (isNaN(a)) ? 0 : a;
    }

简单并做它的功能。

然后我尝试了一个简单的黑客来获得该字段中的任何内容的两位精度:

    function two_digit(amount) {
        amount -= 0;
        amount = ( Math.round(amount*100) )/100;
        return ( amount == Math.floor(amount)) ? amount + '.00' : ( (amount*10 == Math.floor(amount*10) ) ? amount + '0' : amount);
    }

一边评论..我希望那是72个字符宽,但很好。

在输入元素中,我有onfocus / onblur事件:

onFocus="this.style.background='#ffff00';"
onblur="this.style.background='#e7caea'; var var1 = Math.abs(noNaN(parseFloat(this.value)));this.value=two_digit( var1 );"

现在,当我点击该字段时,我会得到一个明亮的黄色背景颜色以及输入正确对齐的数字的能力。我输入5.587,然后单击表单上的任何其他位置,奇妙地,背景颜色变为紫色,字段中的数字变为5.59。

如果我在现场输入“5.874f52”,那么由于onblur,我得到“5.87”。看起来很好。但是,如果我输入“aj44.34.1234”,那么我得到“0.00”而不是“44.34”。

我知道,试图保护自己免受最愚蠢的用户的侵害似乎是不合理的,但如果你只能看到我坚持使用的用户。所以我认真思考了一个简单的js,它在输入字符串中从左到右行走,只提取数字和小数点。因此输入“aj44.34.1234”将变为“44.34.1234”,它与我现在的工作正常并产生“44.34”。输入字符串“$ 2,345.67”当然是明确的NaN并且下降到“0.00”。

所以我想我只是在寻找一种方法来做到这一点,而不做任何淫秽的事情。提前感谢您的任何指示。

方面问题:xhtml中的js事件是小写的“onblur”和“onfocus”,而不是想要“onBlur”和“onFocus”的HTML规范?无论broswers似乎接受了这两个事实。

- 编辑---我忘了添加输入类css:

.inp_num_right
    {  
        font-family: Lucida Console,monospace;
        font-size: 12px;
        font-weight: normal;
        text-align: right;
        padding: 1px;
        margin: 2px;
        background-color: transparent;
        border-style: 1px solid black;
        color: #000000;
    }

1 个答案:

答案 0 :(得分:1)

如果要清理非数字字符,最好使用正则表达式来过滤和删除不需要的字符。这是我为你写的一个函数,它将完成你想用输入过滤器做的所有事情。

function sanitizeNumericInput(input) {

    // a negative sign comes before any digit
    var is_negative = /^[^0-9]*\-/.test(input)

    // remove anything that is not a digit or decimal point
    var digits = input.replace(/[^0-9\.]/g, '');

    // find the first decimal point
    var decimal_point = digits.indexOf('.');

    // no decimal point, don't worry about inserting one
    if(decimal_point == -1) decimal_point = digits.length;

    // remove all other decimal points and create a numeric string
    var clean = (is_negative?'-':'') + digits.substr(0, decimal_point) + '.' + digits.substr(decimal_point).replace(/\./g, '');

    // attempt to turn this into a number data-type
    var number = parseFloat(clean);

    // no digits (not a number) return '0.00'
    if(isNaN(number)) return '0.00';

    // round to two decimal places
    number = Math.round(number*100) / 100);

    // force two digits after the decimal point, convert to string and return it
    return number.toFixed(2)+'';
}

它处理非数字输入,舍入,负数并强制小数位后的两位数

sanitizeNumericInput('az-12charlie8.234567'); // -128.23
sanitizeNumericInput('no numbers'); // 0.00
sanitizeNumericInput('0'); // 0.00
sanitizeNumericInput('123'); // 123.00
sanitizeNumericInput('-123.4'); // -123.40
sanitizeNumericInput('12.459'); // 12.46

另外,我建议您避免使用onbluronfocus属性来运行javascript。看看使用DOM事件绑定,你可以很容易地使用jQuery这样做:

$('#some_num').bind('change', function(){
    this.value = sanitizeNumericInput(this.value);
});