web-dev-qa-db-ja.com

AngularJS番号入力形式のビュー

ユーザーが大きな数字を入力するときに、フォーマットされた数字入力を使用して、ユーザーに千個の区切り点を表示したいと思います。私が使用したディレクティブコードは次のとおりです。 http://jsfiddle.net/LCZfd/3/

input type="text"を使用すると動作しますが、input type="number"を使用したい場合、ユーザーが大きな数字を入力したときに何かがおかしくなります。

input[number]の問題は何ですか?

29
Murat Çorlu

コメントに書かれているように、_input type="number"_は数字、小数点区切り文字(ロケールに応じて通常_,_または_._)、および_-_またはe。それでもenterでも構いませんが、ブラウザは不明な文字や不正な文字を破棄します。

これにより、2つのオプションが得られます。

  • _type="text"_とpattern="[0-9]+([\.,][0-9]+)*"などのパターン検証を使用して、 で行うように値を自動的にフォーマットしながら、ユーザーが入力できる内容を制限します
  • 入力フィールドの上部にオーバーレイを配置して、希望する方法で数値をレンダリングし、ユーザーが ここで説明 のようなカスタム_type="number"_入力コントロールを使用できるようにします

後者のソリューションでは、追加の_<label>_タグを使用します。このタグには、現在の値が含まれ、入力フィールドにフォーカスするとCSSによって非表示になります。

38
S.B.

step属性をnumber入力に追加する必要があります。

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

これにより、浮動小数点が許可されます。

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

また、Firefoxのnumber入力のバグスレッドを確認することをお勧めします。 FFのthisリリースでようやくサポートされたため、この入力タイプを使用してnotを検討することができます。

6
matthewpavkov

この数年後も、このためのHTML5ソリューションはまだありません。

_<input type="tel">_または_<input type="text">_を使用しています(「tel」はAndroidおよびiOS、場合によってはボーナスです)で数字キーボードを表示します。)

次に、次のディレクティブが必要でした。

  • 数字以外の文字を除外する
  • ユーザーが入力するときに、千区切りのカンマを追加します
  • _$parsers_とkeyupを使用してelem.val()と_$formatters_を設定して表示を設定します...
  • ...舞台裏で、_ng-model_に浮動小数点数を割り当てます

以下のディレクティブの例はこれを実行し、正または整数のみを指定しない限り、負と浮動小数点数を受け入れます。

それは私が望む完全な解決策ではありませんが、私はそれがギャップを埋めると思います。

HTML

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

ジャバスクリプト

_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/

6
BenK

あなたはこれを試すことができます、私はここで見たディレクティブを変更しました... 入力を数字のみを受け入れるように制限するにはどうすればよいですか? ...

ここに私が作成した修正されたディレクティブがあります...このディレクティブは、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();
             }
         }
        });
  }

};

あなたはこのように使用します...

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

,は数字のみを使用し、カンマを追加すると文字列になるため、type=numberで値を使用することはできません。

http://jsfiddle.net/LCZfd/5 を参照してください

コンマが必要な場合は、独自のコントロールを作成する方が適切です。真の値(数値)と表示値(文字列)を持つもの。

2
Jahed