代码之家  ›  专栏  ›  技术社区  ›  kaka1234

AngularJS:在自定义ContentEditable指令中限制用户输入

  •  3
  • kaka1234  · 技术社区  · 6 年前

    使用角度JS:

    我有一个HTML表,并对每行数据使用ContentEditable,如下所示:

    <td contenteditable="true" 
        ng-repeat="column in targetTable.columns"
        ng-model="r[column.id]"
        ng-blur="!r.id? addNewRow(r[column.id], r): undefined">
    </td>
    

    我的指令还包括:

    directive('contenteditable', ['$sce', function($sce) {
        return {
          link: function(scope, element, attrs, ngModel) {
    
            var regex =   /^[\w/\s_~`!@#$%^&*()_+-={}[\]|\:;/>\\\'\"]$/;      
            element.on('keypress', (e) => {
                char = String.fromCharCode(event.which);
                if (!regexpInt.test(char)) {
                    event.preventDefault();
                };         
            });
    
            ngModel.$parsers.push(function (value) {
               if (value.length > 5) {
                 value = value.substr(0, 5);
                 ngModel.$setViewValue(value);
                 ngModel.$render();
               }
               return value;
            });
          }
        }
    });
    

    我只是发布指令中的相关代码。整个工作代码可以在下面的代码笔中看到。

    在上面的指令中,我使用regex允许用户键入与spl chars和space一起定义的字符集中的任何内容。

    我也在使用ngmodel.$parsers,试图将用户输入限制为特定的字符限制(在本例中为5),因此如果用户键入的字符超过5,我希望输入停止接受更多的字符。在这里应用限制的原因是,我将创建动态列,并根据列名称应用每个列的最大长度,因此无法在HTML中对应用限制。

    现在问题出现在maxlength代码中,它的工作方式与预期不完全一致。

    • 如果您看到演示并开始键入5个以上的字符,只要您键入第6个字符,光标就会到达第1个字符,如果您键入更多的字符,光标就会一直覆盖现有的字符。

    • 因为我希望在输入中允许空格,所以如果您键入一些字符并添加空格,它将尝试向输入中添加&N b s p;。

    我想从maxlength代码中得到的是,它应该接受空格,一旦您尝试键入超过5个字符,它就会阻止用户键入并自行停止。类似于regex代码。

    下面是我的代码笔演示: https://codepen.io/anon/pen/WKZJWw

    是否有解决此问题的输入?

    1 回复  |  直到 6 年前
        1
  •  2
  •   logee    6 年前

    read

        html = html.replace(/&nbsp;/g, ' ')
        ngModel.$setViewValue(html);
    

       element.on('keypress', (e) => {
          char = String.fromCharCode(event.which)
          if (!regex.test(char)) {
            event.preventDefault();
          }
    
          if (ngModel.$viewValue && ngModel.$viewValue.length >= maxLength) {
                event.preventDefault();
          }
       });
    

    maxLength

      ngModel.$render = function() {
        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
        var caretPosition = (ngModel.$viewValue && ngModel.$viewValue.length) || 0;
        setCaretPosition(caretPosition);
      };
    

    answer

        var setCaretPosition = function(position) {
            if (!element[0].childNodes[0]) {
                  return;
            }
            var range = document.createRange();
            var selection = window.getSelection();
            range.setStart(element[0].childNodes[0], position);
            range.collapse(true);
            selection.removeAllRanges();
            selection.addRange(range);
        };
    

    codepen