问题 如何让textarea不允许或忽略AngularJS中的linebreak / newline / return


在angularjs中是否可以忽略或不允许textarea中的换行符?该文本用于pdf生成器,我不希望用户能够键入换行符然后在pdf中看不到它。我宁愿一起忽略返回键。

<textarea ng-model="model.text"></textarea>

12198
2018-05-08 20:42


起源

你什么意思?它已经被忽略了 (例)  - 添加换行符,输出仍然是一行。 - Tom
@Tom还有换行符,它只是没有显示它们。我在服务器端php生成器脚本中使用该文本,它打印换行符。我希望根本不允许新行字符(不在textarea中显示它们),用户不认为他们可以有新行。 - Tom Krones


答案:


在您的控制器/指令中,如果运行正则表达式以删除所有出现的'\ n' $scope.model.text,你应该得到一个没有换行符的普通字符串。

您可以参考这个答案来做到这一点: 如何在JavaScript中替换所有出现的字符串?

如果您甚至不希望文本区域有任何换行符,您可以在观察者中添加上述逻辑,如下所示:

$scope.$watch('model.text', function(){
  $scope.model.text = $scope.model.text.replace(/\n/g, '');
})

6
2018-05-08 21:01



这可以工作,我想这样做,但我不希望用户认为他们可以使用换行,然后在最终产品中看不到它们。我宁愿不允许他们输入换行符。 - Tom Krones
我已经编辑了答案,即使文本区域没有换行符(使用观察者)。用户现在可以获得他在文本区域中看到的内容。 :) - midhunsezhi
太好了!除非你在textarea的末尾添加换行符然后它不会触发$ watch,否则这种方法有效。不确定为什么...我认为默认情况下,angular修剪textarea中的文本,因此模型不会更改,也不会触发$ watch。 - Tom Krones


使用GísliKonráð和midhunsezhi答案,我能够制定一个符合我想要的指令。信用应该真正归功于他们。

.directive('noNewLines', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attributes, ngModelController) {
            var model = attributes.ngModel;
            var regex = new RegExp("^[^\n\r]*$");

            // $parsers handle input from the element where the
            // ng-model directive is set
            ngModelController.$parsers.unshift(function(value) {
                if(!value) return value;
                var modelValue = ngModelController.$modelValue;
                var isValid = regex.test(value);
                ngModelController.$setValidity('Does not match pattern', isValid);

                var transformedInput = value.replace(/[\n\r]/g, '');
                if(transformedInput !== value) {
                    ngModelController.$setViewValue(transformedInput);
                    ngModelController.$render();
                }
               return transformedInput;
            });

            // $formatters handle when the model is changed and 
            // the element needs to be updated
            ngModelController.$formatters.unshift(function(value) {
               if(!value) return value;
               var isValid = regex.test(value);
               ngModelController.$setValidity('Does not match pattern', isValid);
               return value;
            });

            element.on('keypress', function(e) {
                var char = String.fromCharCode(e.which);
                var text = angular.element(e.srcElement).val();
                if(!regex.test(char) || !regex.test(text)) {
                    event.preventDefault();   
                }                   
            });

        }
   };
 });

它的使用方式如下:

<textarea ng-model="text" no-new-lines></textarea>

5
2018-05-19 19:29





这是您可以使用的指令。它有阻止无效输入和忽略大小写的选项。

.directive('taPattern', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attributes, ngModelController) {
            var pattern = attributes.taPattern;  
            var flag = attributes.taPatternIgnoreCase === true ? 'i' : undefined;
            var blockInvalidInput = attributes.hasOwnProperty('taPatternBlockInvalid');
            var model = attributes.ngModel;
            if(!pattern) return;
            if(pattern[0] != '^')
                pattern = '^' + pattern;
            if(pattern[pattern.length - 1] != '$')
                pattern += '$';

            var regex = new RegExp(pattern, flag);

            // $parsers handle input from the element where the
            // ng-model directive is set
            ngModelController.$parsers.unshift(function(value) {
               if(!value) return value;
               var modelValue = ngModelController.$modelValue;
               var isValid = regex.test(value);
               ngModelController.$setValidity('Does not match pattern', isValid);
               return value;
            });

            // $formatters handle when the model is changed and 
            // the element needs to be updated
            ngModelController.$formatters.unshift(function(value) {
               if(!value) return value;
               var isValid = regex.test(value);
               ngModelController.$setValidity('Does not match pattern', isValid);
               return value;
            });

            if(blockInvalidInput){                    
                element.on('keypress', function(e) {
                    var char = String.fromCharCode(e.which);
                    var text = angular.element(e.srcElement).val();
                    if(!regex.test(char) || !regex.test(text)) {
                        event.preventDefault();   
                    }                   
                });
            }

        }
   };
 });

你可以在这里看到它的演示: https://jsfiddle.net/mr59xf3z/3/


1
2018-05-19 16:21



真棒!最好的答案!除非您复制并粘贴具有换行符的文本,否则效果很好。可以使用@midhunsezhi修复它 $watch() 解决方案与此指令相结合,但我宁愿不使用两种解决方案,在复制它们时以任何方式过滤我们的换行符? - Tom Krones


使用 <input 代替 <textarea 并设置像textarea的高度。

input.textarea {
  height: 100px;
  
  word-break: break-word;
  width: 300px;
}
<input class="textarea">


-2
2018-05-13 00:47



好想法。我尝试了它,它非常接近。它的工作原理除了文本在中间垂直对齐 input 哪个与之不符 textarea 样式。有什么方法可以修复它,使文本垂直对齐顶部? - Tom Krones
这不是正确的答案,因为输入框无法包装文本。所以它不会像预期的那样工作。您可以将文本与css中的顶部对齐,但您将始终只有一行文本。一旦到达输入框的末尾,它就会溢出。 - Filip Kis