角度限制输入仅限于粘贴时的数字

时间:2017-01-24 12:53:31

标签: javascript angularjs angularjs-directive

我有一个在<input type='text'>中运行的指令来限制用户输入只键入数字。工作正常!

我的问题是,如果用户复制/粘贴一些字符串,则angular接受该值并将字符串发送到后端。

angular.module('autonumeric', []).directive('ngNumeric', [function () {
'use strict';
// Declare a empty options object
var options = {};
return {
    // Require ng-model in the element attribute for watching changes.
    require: '?ngModel',
    // This directive only works when used in element's attribute (e.g: cr-numeric)
    restrict: 'A',
    compile: function (tElm, tAttrs) {

        var isTextInput = tElm.is('input:text');

        return function (scope, elm, attrs, controller) {
            // Get instance-specific options.
            var opts = angular.extend({}, options, scope.$eval(attrs.crNumeric));

            // Helper method to update autoNumeric with new value.
            var updateElement = function (element, newVal) {
                // Only set value if value is numeric
                if ($.isNumeric(newVal))
                    element.autoNumeric('set', newVal);
            };    

            // Initialize element as autoNumeric with options.
            elm.autoNumeric(opts);

            // if element has controller, wire it (only for <input type="text" />)
            if (controller && isTextInput) {
                // render element as autoNumeric
                controller.$render = function () {
                    updateElement(elm, controller.$viewValue);
                }
                // watch for external changes to model and re-render element
                scope.$watch(tAttrs.ngModel, function (current, old) {
                    //controller.$render();
                    updateElement(elm, controller.$viewValue);
                });
                // Detect changes on element and update model.
                elm.on('change', function (e) {
                    scope.$apply(function () {
                        controller.$setViewValue(elm.autoNumeric('get'));
                    });
                });
            }
            else {
                // Listen for changes to value changes and re-render element.
                // Useful when binding to a readonly input field.
                if (isTextInput) {
                    attrs.$observe('value', function (val) {
                        updateElement(elm, val);
                    });
                }
            }
        }
    } // compile
} // return
}]);

我尝试使用正则表达式replace(/[^0-9.]/g, '')替换删除所有字符,但无效。 有人知道如何改进这个指令,即使在复制/粘贴时也只接受数字吗?

2 个答案:

答案 0 :(得分:1)

我写了一个类似的指令,只允许浮点数(并且还将,转换为.)。这是最简单的,所以我认为你可以使用它:

angular.module('myMod').directive('floatOnly', function() {
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, element, attrs, modelCtrl) {
            modelCtrl.$parsers.push(function(inputValue) {
                if(inputValue === undefined) return '';

                // Remove forbidden characters
                cleanInputValue = inputValue.replace(',', '.') // change commas to dots
                                            .replace(/[^\d.]/g, '') // keep numbers and dots
                                            .replace(/\./, "x") // change the first dot in X
                                            .replace(/\./g, "") // remove all dots
                                            .replace(/x/, "."); // change X to dot
                if(cleanInputValue != inputValue) {
                    modelCtrl.$setViewValue(cleanInputValue);
                    modelCtrl.$render();
                }
                return cleanInputValue;
            });
        }
    }
});

您可以按照以下方式使用它:

<input type="text" ng-model="myFloat" float-only/>

Demo on JSFiddle

答案 1 :(得分:0)

通常情况下,我认为您使用<input type='number'>会更好。还要记住,你的后端应该是强大的,你不应该相信来自客户端的东西,即使你的花哨指令也是如此。

如果您坚持使用文本输入,也许可以从该指令中获得灵感。

app.directive('ngNumeric', [function () {
  return {
    restrict: 'E',
    require: 'ngModel',
    scope: {
      model: '=ngModel'
    },
    compile: compile,
    replace: true,
    template: '<input type="text" ng-change="change()">'
  }

  function compile() {
    return link
  }

  function link(scope, element) {
    scope.change = function() {
    var numeric = element.val().replace(/[^0-9]/g, '')
    console.log('I changed', element.val())
    element.val(numeric)
    scope.model = numeric
    }
  }
}]);

Demo on Plunker