如何防止在角度观察的输入字段上输入错误用户?

时间:2013-03-07 06:03:58

标签: javascript angularjs

我在分页的网格上有一个观察的输入字段。类似于28页的X.

我希望用户能够更改输入,但我也希望防止输入错误。

我的支票是> = 1或< =最大页数(在这种情况下为28)。输入默认为1。

我通过将新值与这些约束进行比较来完成此操作,如果失败,则恢复为旧值。当有人想输入20时,问题就出现了。这要求他们删除1,并输入20.一旦删除1,它就会使约束失败并恢复为1,从而无法输入20。

无论如何在没有从$ watch中删除它的情况下完成此操作?

2 个答案:

答案 0 :(得分:2)

您可以使用<input type="number">和您自己的指令的组合,该指令具有blur事件的解析器和侦听器。这样,您的手表只会在页码有效页面时执行,或者在输入无效时使用null执行一次,但用户可以输入任何内容直到模糊事件触发。像这样:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        $scope.pageNumber = 1;
    })
    .directive('myPagenumber', function() {
        return {
            require: 'ngModel',
            link: function($scope, elem, attrs, ctrl) {
                $scope.$watch(attrs.ngModel, function(val) {
                    console.log('ng-model value: ' + val);
                });

                var parsePage = function(val) {
                    var num = parseInt(val, 10);
                    if (isNaN(num)) {
                        return null;
                    } else if (num > 28 || num < 1) {
                        return 1;
                    } else {
                        return num;
                    }
                }

                ctrl.$parsers.push(function(val) {
                    return parsePage(val);
                });

                elem.bind('blur', function() {
                    var page = parsePage(elem.val());
                    if (page === null) 
                        page = 1;

                    $scope.$apply(function() {
                        ctrl.$setViewValue(page);
                        ctrl.$render();
                    });
                });
            }
        };
    });
    </script>
</head>
<body ng-controller="Ctrl">
    <input type="number" ng-model="pageNumber" my-pagenumber>
</body>
</html>

答案 1 :(得分:-1)

我为你写了一个例子:

var min = 1;
var max = 28;
$('.page').live('keydown', function (e){      
      var currentVal = $(this).val();
      //enter,tab, shift
      if(e.which == 37 || e.which == 39 || e.which == 9 || e.which == 8) {
          return;
      // key up
      } else if(e.which == 38){
          if(currentVal < max){
             currentVal++;
          }
          $(this).val(currentVal);
      //key down    
      } else if( e.which == 40) {
        if(currentVal > min){
             currentVal--;
          }
          $(this).val(currentVal);
      //only numbers    
      } else if(e.which >= 48 && e.which <= 57){
        var val = e.which - 48;
        if(e.target.selectionEnd == e.target.selectionStart) {
          val = currentVal.insert(e.target.selectionEnd, val);
        } else {
          val = currentVal.replace(currentVal.substr(getSelectionStart(e.target),getSelectionEnd(e.target)),val);
        }
        if(min<=val && val <= max) {
          $(this).val(val);
        }
      }
      e.preventDefault();
});

// utility functions
//get the start index of the user selection
function getSelectionStart(o) {
    if ( typeof o.selectionStart != 'undefined' )
      return o.selectionStart;

    // IE And FF Support
    o.focus();
    var range = o.createTextRange();
    range.moveToBookmark(document.selection.createRange().getBookmark());
    range.moveEnd('character', o.value.length);
    return o.value.length - range.text.length;
};
//get the end index of the user selection
function getSelectionEnd(o) {
    if ( typeof o.selectionEnd != 'undefined' )
      return o.selectionEnd;

    // IE And FF Support
    o.focus();
    var range = o.createTextRange();
    range.moveToBookmark(document.selection.createRange().getBookmark());
    range.moveStart('character', - o.value.length);
    return range.text.length;
};
/*
* Insert Text at a index
*/
String.prototype.insert = function (index, string) {
  if (index > 0)
    return this.substring(0, index) + string + this.substring(index, this.length);
  else
    return string + this;
};

动画示例:http://jsfiddle.net/PVxqe/1/