Html AngularJS 数字输入格式化视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24001895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 01:57:16  来源:igfitidea点击:

AngularJS number input formatted view

angularjshtmlangularjs-directiveangularjs-ng-model

提问by Murat ?orlu

I want to use a formatted number input to show thousand seperator dots to user when he types big numbers. Here is the directive code that I used: http://jsfiddle.net/LCZfd/3/

我想使用格式化的数字输入在用户键入大数字时向用户显示千个分隔符点。这是我使用的指令代码:http: //jsfiddle.net/LCZfd/3/

When I use input type="text"it works, but when I want to use input type="number"it's weirdly cleaning by something when user typing big numbers.

当我使用input type="text"它时可以工作,但是当我想使用input type="number"它时,当用户输入大数字时,它会奇怪地被某些东西清理干净。

What is problem about input[number]?

有什么问题input[number]

回答by S.B.

As written in the comments, input type="number"doesn't support anything but digits, a decimal separator (usually ,or .depending on the locale) and -or e. You may still enterwhatever you want, but the browser will discard any unknown / incorrect character.

正如评论中所写,input type="number"除了数字、小数点分隔符(通常,.取决于语言环境)和-e. 您仍然可以输入您想要的任何内容,但浏览器将丢弃任何未知/不正确的字符。

This leaves you with 2 options:

这给您留下了 2 个选择:

  • Use type="text"and pattern validation like pattern="[0-9]+([\.,][0-9]+)*"to limit what the user may enter while automatically formatting the value as you do in your example.
  • Put an overlay on top of the input field that renders the numbers how you want and still allows the user to use the custom type="number"input controls, like demonstrated here.
  • 使用type="text"和模式验证pattern="[0-9]+([\.,][0-9]+)*"来限制用户可能输入的内容,同时像您在示例中所做的那样自动设置值的格式。
  • 在输入字段的顶部放置一个叠加层,以您想要的方式呈现数字,并且仍然允许用户使用自定义type="number"输入控件,如演示here

The latter solution uses an additional <label>tag that contains the current value and is hidden via CSS when you focus the input field.

后一种解决方案使用<label>包含当前值的附加标签,并在您聚焦输入字段时通过 CSS 隐藏。

回答by BenK

All these years later, there still isn't an HTML5 solution out of the box for this.

这么多年过去了,仍然没有现成的 HTML5 解决方案。

I am using <input type="tel">or <input type="text">("tel" brings up a numeric keyboard in Android and iOS, which in some cases is a bonus.)

我正在使用<input type="tel"><input type="text">(“tel”在 Android 和 iOS 中使用数字键盘,在某些情况下这是一个奖励。)

Then I needed a directive to:

然后我需要一个指令:

  • filter out non-numeric characters
  • add thousand-separator commas as the user types
  • use $parsersand keyupto set elem.val()and $formattersto set the display...
  • ...while behind the scenes, assign ng-modela floating point number
  • 过滤掉非数字字符
  • 在用户键入时添加千位分隔符逗号
  • 使用$parserskeyup来设置elem.val()$formatters设置显示...
  • ...在幕后,分配ng-model一个浮点数

The directive example below does this, and it accepts negatives and floating point numbers unless you specify you want only positive or integers.

下面的指令示例执行此操作,它接受负数和浮点数,除非您指定只需要正数或整数。

It's not the full solution I would like, but I think it bridges the gap.

这不是我想要的完整解决方案,但我认为它弥补了差距。

HTML

HTML

<input type="text" ng-model="someNumber" number-input />

JAVASCRIPT

爪哇脚本

myApp.directive('numberInput', function($filter) {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ngModelCtrl) {

      ngModelCtrl.$formatters.push(function(modelValue) {
        return setDisplayNumber(modelValue, true);
      });

      // it's best to change the displayed text using elem.val() rather than
      // ngModelCtrl.$setViewValue because the latter will re-trigger the parser
      // and not necessarily in the correct order with the changed value last.
      // see http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/
      // for an explanation of how ngModelCtrl works.
      ngModelCtrl.$parsers.push(function(viewValue) {
        setDisplayNumber(viewValue);
        return setModelNumber(viewValue);
      });

      // occasionally the parser chain doesn't run (when the user repeatedly 
      // types the same non-numeric character)
      // for these cases, clean up again half a second later using "keyup"
      // (the parser runs much sooner than keyup, so it's better UX to also do it within parser
      // to give the feeling that the comma is added as they type)
      elem.bind('keyup focus', function() {
        setDisplayNumber(elem.val());
      });
      function setDisplayNumber(val, formatter) {
        var valStr, displayValue;

        if (typeof val === 'undefined') {
          return 0;
        }

        valStr = val.toString();
        displayValue = valStr.replace(/,/g, '').replace(/[A-Za-z]/g, '');
        displayValue = parseFloat(displayValue);
        displayValue = (!isNaN(displayValue)) ? displayValue.toString() : '';

        // handle leading character -/0
        if (valStr.length === 1 && valStr[0] === '-') {
          displayValue = valStr[0];
        } else if (valStr.length === 1 && valStr[0] === '0') {
          displayValue = '';
        } else {
          displayValue = $filter('number')(displayValue);
        }
        // handle decimal
        if (!attrs.integer) {
          if (displayValue.indexOf('.') === -1) {
            if (valStr.slice(-1) === '.') {
              displayValue += '.';
            } else if (valStr.slice(-2) === '.0') {
              displayValue += '.0';
            } else if (valStr.slice(-3) === '.00') {
              displayValue += '.00';
            }
          } // handle last character 0 after decimal and another number
          else {
            if (valStr.slice(-1) === '0') {
              displayValue += '0';
            }
          }
        }

        if (attrs.positive && displayValue[0] === '-') {
          displayValue = displayValue.substring(1);
        }

        if (typeof formatter !== 'undefined') {
          return (displayValue === '') ? 0 : displayValue;
        } else {
          elem.val((displayValue === '0') ? '' : displayValue);
        }
      }
      function setModelNumber(val) {
        var modelNum = val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, '');
        modelNum = parseFloat(modelNum);
        modelNum = (!isNaN(modelNum)) ? modelNum : 0;
        if (modelNum.toString().indexOf('.') !== -1) {
          modelNum = Math.round((modelNum + 0.00001) * 100) / 100;
        }
        if (attrs.positive) {
          modelNum = Math.abs(modelNum);
        }
        return modelNum;
      }
    }
  };
});

https://jsfiddle.net/benlk/4dto9738/

https://jsfiddle.net/benlk/4dto9738/

回答by matthewpavkov

You need to add the stepattribute to your numberinput.

您需要将该step属性添加到您的number输入中。

<input type="number" step="0.01" />

This will allow floating points.

这将允许浮点数。

http://jsfiddle.net/LCZfd/1/

http://jsfiddle.net/LCZfd/1/

Also, I'd recommend reviewing the bug thread on numberinputs in Firefox. You may want to consider notusing this input type, as it was just finally supported in thisrelease of FF.

另外,我建议您查看numberFirefox 中输入的错误线程。您可能需要考虑使用此输入类型,因为版本的 FF才最终支持它。

回答by Jahed

You cannot use values with ,because type=numberonly takes numbers, adding a comma makes it a string.

您不能使用值 with,因为type=number只接受数字,添加逗号使其成为字符串。

See http://jsfiddle.net/LCZfd/5

http://jsfiddle.net/LCZfd/5

You're better off making your own controls if you want commas. One with a true value (the number) and a display value (the string).

如果你想要逗号,你最好制作自己的控件。一个具有真值(数字)和显示值(字符串)。

回答by sireken

you can try this, I modified the directive I saw here... How do I restrict an input to only accept numbers?...

你可以试试这个,我修改了我在这里看到的指令...... 如何限制输入只接受数字?...

here's the modified directive I made... This directive uses the keyup event to modify the input on the fly...

这是我制作的修改后的指令...该指令使用 keyup 事件来动态修改输入...

.directive('numericOnly', function($filter) {
 return {
  require: 'ngModel',
  link: function(scope, element, attrs, modelCtrl) {

       element.bind('keyup', function (inputValue, e) {
         var strinput = modelCtrl.$$rawModelValue;
         //filter user input
         var transformedInput = strinput ? strinput.replace(/[^,\d.-]/g,'') : null;
         //remove trailing 0
         if(transformedInput.charAt(0) <= '0'){
           transformedInput = null;
           modelCtrl.$setViewValue(transformedInput);
           modelCtrl.$render();
         }else{
           var decimalSplit = transformedInput.split(".")
           var intPart = decimalSplit[0];
           var decPart = decimalSplit[1];
           //remove previously formated number
           intPart = intPart.replace(/,/g, "");
           //split whole number into array of 3 digits
           if(intPart.length > 3){
             var intDiv = Math.floor(intPart.length / 3);
             var strfraction = [];
             var i = intDiv,
                 j = 3;

             while(intDiv > 0){
               strfraction[intDiv] = intPart.slice(intPart.length-j,intPart.length - (j - 3));
               j=j+3;
               intDiv--;
             }
             var k = j-3;
             if((intPart.length-k) > 0){
               strfraction[0] = intPart.slice(0,intPart.length-k);
             }
           }
           //join arrays
           if(strfraction == undefined){ return;}
             var currencyformat = strfraction.join(',');
             //check for leading comma
             if(currencyformat.charAt(0)==','){
               currencyformat = currencyformat.slice(1);
             }

             if(decPart ==  undefined){
               modelCtrl.$setViewValue(currencyformat);
               modelCtrl.$render();
               return;
             }else{
               currencyformat = currencyformat + "." + decPart.slice(0,2);
               modelCtrl.$setViewValue(currencyformat);
               modelCtrl.$render();
             }
         }
        });
  }

};

};

you use it like this ...

你这样用...

<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />