需要使用js限制可接受的输入框值(和文本长度)

时间:2018-09-18 19:13:03

标签: javascript html angularjs

使用以下代码将输入框的输入限制为仅数字(无字母,无特殊字符),前两个框的输入限制为3个字符,第三个框的输入限制为4个字符。但是我无法阻止用户输入特殊字符(用户按下Shift +数字来获取特殊字符),也无法将每个框的字符数分别限制为3、3和4。我的代码丢失了什么?另外,这些文本框在Chrome中的行为尤其奇怪-Chrome甚至不允许我在任何输入框中输入任何值。我还希望允许在这些框中使用Ctrl-c,Ctrl-x和Ctrl-v(复制,剪切和粘贴数据),但无法弄清楚如何实现它们。对于它的价值,我已经浏览了有关此主题的一些建议,但仍无法修复我的代码。

rvPhoneInput.js中的代码:

(function(angular) {
  'use strict';

  angular.module('rvComponents')
    .component('rvPhoneInput', {
      bindings: {
        compare: '=?',
        form: '<',
        inline: '<?',
        isRequired: '<?',
        label: '@?',
        name: '@',
        nextElem: '@?',
        value: '=',
        isDisabled: '<?'
      },
      controller: PhoneInputController,
      require: {
        modelCtrl: 'ngModel',
        modelOptsCtrl: 'ngModelOptions'
      },
      templateUrl: './components/rvPhoneInput/rvPhoneInput.html'
    });

  function PhoneInputController($element, $scope, $window) {
    var ctrl = this;

    ctrl.phone = [
      {
        name: ctrl.name + 1,
        num: ''
      },
      {
        name: ctrl.name + 2,
        num: ''
      },
      {
        name: ctrl.name + 3,
        num: ''
      }
    ];

    ctrl.modelOpts = {
      allowInvalid: true
    };
    $element.attr('ng-model-options', JSON.stringify(ctrl.modelOpts));

    $scope.$watch('$ctrl.value', function(newVal) {
      if (newVal) {
        if (newVal.length === 10) {
          ctrl.phone[0].num = newVal.substring(0, 3);
          ctrl.phone[1].num = newVal.substring(3, 6);
          ctrl.phone[2].num = newVal.substring(6, 10);
        }
      } else {
        ctrl.phone[0].num = ctrl.phone[1].num = ctrl.phone[2].num = '';
      }
    });

    $scope.$watchGroup(['$ctrl.phone[0].num', '$ctrl.phone[1].num', '$ctrl.phone[2].num'], function(newVals) {
      var newPhoneNum = (newVals[0] || '') + (newVals[1] || '') + (newVals[2] || '');
      if (newPhoneNum) {
        if (ctrl.value !== newPhoneNum) {
          ctrl.value = newPhoneNum;
          ctrl.modelCtrl && ctrl.modelCtrl.$setViewValue(newPhoneNum);
        }
      } else {
        ctrl.value = undefined;
      }
    });

    ctrl.$onInit = function() {
      if (ctrl.modelCtrl) {
        ctrl.modelCtrl.$validators.sameNum = function(modelVal) {
          return !modelVal || !ctrl.compare || (modelVal && modelVal !== ctrl.compare);
        };
        ctrl.modelCtrl.$validators.phoneLength = function(modelVal) {
          return !modelVal || (modelVal && modelVal.length === 10);
        };
      }
      if (ctrl.modelOptsCtrl) {
        angular.merge(ctrl.modelOptsCtrl.$options, ctrl.modelOpts);
      }
    };

    $element.on('phoneFocus', function(evt) {
      $element.find('input[name="'+ctrl.phone[0].name+'"]').focus();
    });

    ctrl.maxlength = maxlength;
    ctrl.validateRequired = validateRequired;

    function maxlength(e, max, pos) {
      if (e.which === 9 || e.which === 13 || e.which === 16) {
        return true;
      }

      var isBackspace = e.which === 8;
      var isLeftArrow = e.which === 37;
      var isRightArrow = e.which === 39;          

      if (!isBackspace && !isLeftArrow && !isRightArrow && (e.which < 48 || e.which > 57)) {
      return e.preventDefault();
      }

      var inputLength = (ctrl.phone[pos].num || '').length;
      if (inputLength === max - 1 || ((inputLength === 1 || !inputLength) && isBackspace)) {
        var watcher = $scope.$watch(function() {
          return (ctrl.phone[pos].num || '').length;
        }, function(newVal) {
          // focus to next element when input's pre-determined length is reached
          if (newVal === (pos === 2 ? 4 : 3) || !newVal) {
            var elem;
            if (!newVal) {
              elem = $element.find('input[name="'+ctrl.phone[pos === 0 ? pos : pos-1].name+'"]');
            } else {
              elem = (pos === 2) ? $(ctrl.nextElem) : $element.find('input[name="'+ctrl.phone[pos+1].name+'"]');
            }
            elem.focus();

            // destroy watch
            watcher();
          }
        });
      } else if (inputLength >= max && !isBackspace && !isLeftArrow && !isRightArrow) {
        e.preventDefault();
      }
    }

    function validateRequired() {
      return ctrl.form.$submitted && ctrl.phone.every(function(phone) {
        return ctrl.form[phone.name].$error.required;
      }) && !ctrl.isDisabled;
    }
  }

  PhoneInputController.$inject = ['$element', '$scope', '$window'];
})(angular);

这是我的html文件(rvPhoneInput.html)中的代码:

<div ng-class="$ctrl.inline ? 'form-inline' : 'form-group'">
  <label ng-if="$ctrl.label">{{$ctrl.label}}<span style="color:red;" ng-if="$ctrl.isRequired">*</span></label>
  <div ng-class="$ctrl.inline ? 'd-inline-block' : ''">
    <span class="color-black">(</span>
    <input type="text" name="{{$ctrl.phone[0].name}}" class="form-control" ng-model="$ctrl.phone[0].num" ng-required="$ctrl.isRequired"
      ng-minlength="3" ng-model-options="$ctrl.modelOpts" ng-keydown="$ctrl.maxlength($event, 3, 0)" ng-disabled="$ctrl.isDisabled">
    <span class="color-black">)</span>
    <input type="text" name="{{$ctrl.phone[1].name}}" class="form-control" ng-model="$ctrl.phone[1].num" ng-required="$ctrl.isRequired" ng-disabled="$ctrl.isDisabled"
      ng-minlength="3" ng-model-options="$ctrl.modelOpts" ng-keydown="$ctrl.maxlength($event, 3, 1)">
    <span class="color-black">-</span>
    <input type="text" name="{{$ctrl.phone[2].name}}" class="form-control" ng-model="$ctrl.phone[2].num" ng-required="$ctrl.isRequired" ng-disabled="$ctrl.isDisabled"
      ng-minlength="4" ng-model-options="$ctrl.modelOpts" ng-keydown="$ctrl.maxlength($event, 4, 2)">
  </div>
  <div ng-if="$ctrl.validateRequired()" class="error-label">
    <div class="text-danger">This is a required field.</div>
  </div>
  <div ng-messages="$ctrl.form.$submitted && $ctrl.form[$ctrl.name].$error" class="error-label">
    <div class="text-danger" ng-message="sameNum">Your <span style="text-transform: lowercase">{{$ctrl.label}}</span> cannot be the same as your cell number.</div>
    <div class="text-danger" ng-message="phoneLength">Phone number must be 10 digits.</div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

我不知道 Angular 的处理方式(我使用“ Vue”),但此代码段仅允许在字段中键入数字,括号,空格和破折号。如果需要,您可以使用var regx = /\d/;

首先,我使用type="tel"-它并不能帮助您进行输入限制或验证,但是确实提示移动设备可以优化自定义键盘用于电话输入。

var regx = /[0-9 ()-]/;
var inp = document.getElementById('field1');

inp.addEventListener('keypress', function(e) {
    console.log('key: ' + e.key);
    if (! e.key.match(regx)) {
        // if the key doesn't match the allowed characters,
        // prevent it from being entered.
        e.preventDefault();
    }
});
<form action="#">
    <label for="field1">Phone:</label>
    <input type="tel" id="field1" name="stuff" placeholder="Enter Phone" />
</form>

此限制确保仅键入允许的字符,但仍需要验证-例如,这将允许您键入7)-3 82(-),该字符仅包含允许的字符,但显然无效。

您可以使用html5 pattern验证,但最终可能会局限性...例如,当我接受电话输入时,我允许使用多种格式:(nnn) nnn-nnnn,{{1 }},nnnnnnnnnnnnn-nnn-nnnn(甚至不算国际电话号码)

别忘了在客户端的JS中验证和在服务器上的验证。

有关“电话”输入类型的更多信息,请参见the MDN doc,尤其是 Validation 部分。

当然,有人可能已经为电话号码编写了Angular小部件,因此您不必自己编写。