web-dev-qa-db-ja.com

angular validate input type = "number"

このようなマークアップがあります:

<form name="myForm" ng-controller="myCtrl" novalidate>
    <input ng-model="theValue" type="range" min="0" max="100" required>
    <input ng-model="theValue" type="number" required></input>
    <span ng-show="theValue.$error.number">Hey! No letters, buddy!</span>
</form>

そして、ユーザーが誤って2番目の入力に文字を入力したときにスパンを表示したいのです。シンプルでしょ? (おそらく)関連する問題として、ユーザーが最初のスライダー入力を移動すると、2番目の入力の値が消えます。どうして? type-numberをマークアップから削除しても、これは起こりません。

明確にするために、「送信」アクションなしで、入力された直後にツールチップエラーをユーザーに表示するようにします。 (実際にはform要素をまったく使用する必要はありませんが、関連するすべてのデモで必要なようです。)

http://jsfiddle.net/7FfWT/

回避策は大歓迎です。可能であれば、作業フィドルを投稿してください。

18
Ben

type="number"が他のinputsとうまく動作するという奇妙な問題があるようです。

このGoogleグループの投稿の投稿は、あなたを正しい軌道に乗せるはずです。特に、そこの最後の投稿: https://groups.google.com/forum/#!msg/angular/Ecjx2fo8Qvk/x6iNlZrO_mwJ

Jsfiddleリンク: http://jsfiddle.net/ABE8U/

回避策として、彼はディレクティブを作成しました:

.directive('toNumber', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            ctrl.$parsers.Push(function (value) {
                return parseFloat(value || '');
            });
        }
    };
});

シュムリラスキンの功績

16
jzm

また、ng-patternをバリデーターとして使用できます。

<input type="number" ng-model="theValue" name="theValue" step="1" min="0" max="10"  ng-pattern="integerval" required>
<span ng-show="form.theValue.$invalid">Hey! No letters, buddy!</span>

$scope.integerval = /^\d*$/;
15
zenio

Ng-repeatフィルターで動作するようにディレクティブを更新しました。 「$」に注意してください。これはワイルドカードです。このディレクティブは0をうまく処理するはずです。ワイルドカードにフェイルオーバーします

.directive('toNumber', function() {
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
            ctrl.$parsers.Push(function(value) {
                return value===0 ? 0 : (parseFloat(value) || '$');
            });
    };
})
1
FesterCluck

jzmの答えは本当に素晴らしいトリックであり、私の時間を節約しました。

私はそれをさらに一歩進めて、parseFloat(value)を実際の動作に置き換えています。

directive('number', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ngModel) {

            ngModel.$parsers.Push(function (value) {
                if (value==null)
                  return NaN;
            });
        }
    };
});
0
immirza

入力として '0'が必要になるまで、jzmの答えは私のために働きました。 jzmのコードを調整しました:

_.directive('toNumber', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            ctrl.$parsers.Push(function (value) {
                if (value === 0)
                    return 0;

                return parseFloat(value || '');
            });
        }
    };
});
_

if (value === 0)ブロックの追加に注意してください。

JavaScriptの論理比較を私よりもよく理解している人は、おそらくよりエレガントなコードを作成できます。

0
Jeremy