【问题标题】:AngularJS: Limiting the user input in custom contenteditable directiveAngularJS:限制自定义 contenteditable 指令中的用户输入
【发布时间】:2019-01-04 14:05:28
【问题描述】:

在这里使用 Angular 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;
        });
      }
    }
});

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

在上面的指令中,我使用正则表达式来允许用户从定义的字符集中键入任何内容以及 spl 字符和空格,这可以正常工作。

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

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

  • 如果您看到演示并开始输入超过 5 个字符,一旦您输入第 6 个字符,光标就会到达第一个字符,如果您输入更多字符,则会继续覆盖现有字符。

    李>
  • 由于我想在输入中留出空格,如果您键入一些字符并添加空格,它会尝试添加 &n b s p;到输入。

我对 maxlength 代码的要求是,它应该接受空格,并且一旦您尝试输入超过 5 个字符,它就会阻止用户输入并自行停止。类似于正则表达式代码。

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

有解决此问题的意见吗?

【问题讨论】:

  • 有人输入吗?
  • 看看这是否有帮助stackoverflow.com/questions/512528/…
  • 此代码看起来与来自user1563677this question 中的代码相同。这里发生了什么?您是否使用两个帐户来回答您的问题?
  • 使用内联编辑模式。我怀疑你是否能正常工作。
  • @georgeawg 不,我没有 2 个帐户。那是我的队友之一。我们都在开发相同的应用程序但不同的模块。两者都必须处理这个内容可编辑但不同的问题。我们不想创建一个包含 2 个很多问题的帖子。我们只是在维护应用程序,所以现在无法进行太大更改并替换 contenteditable。

标签: angularjs angularjs-directive contenteditable


【解决方案1】:

为了允许空格,我会在设置模型值之前将其删除。所以在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 是 5。但在粘贴输入或用户输入非常快的情况下,您仍然需要重新渲染。要解决此问题,请在每次渲染后将插入符号的位置设置为输入的末尾。

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

感谢 Tim Down 撰写的 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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-07-18
  • 2017-10-29
  • 2014-08-28
  • 2018-06-22
  • 2014-06-24
  • 2017-03-12
  • 2021-01-08
  • 1970-01-01
相关资源
最近更新 更多