Как сделать textarea не разрешать или игнорировать linebreak/newline/return в AngularJS

Можно ли игнорировать или не допускать разрывы строк в текстовой области в angularjs? Текст используется в генераторе pdf, и я не хочу, чтобы пользователь мог вводить новую строку, а затем не видеть ее в pdf. Я предпочел бы, чтобы ключ возврата игнорировался вместе.

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

Ответ 1

Используя ответы Gísli Konráð и 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>

Ответ 2

В вашем контроллере/директиве, если вы запустите регулярное выражение для удаления всех вхождений '\n' в $scope.model.text, вы должны получить простую строку без символов новой строки.

Вы можете обратиться к этому ответу, чтобы сделать это: Как заменить все вхождения строки в JavaScript?

Если вы не хотите, чтобы даже текстовая область имела какие-либо разрывы строк, вы можете добавить указанную выше логику в наблюдатель, как это:

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

Ответ 3

Вот директива, которую вы могли бы использовать. Он имеет опции для блокировки недопустимого ввода и для игнорирования случая.

.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/

Ответ 4

Просто обновление для более новых версий Angular:

component.html:

Поймайте событие keyup, так как в этой точке связанная переменная будет содержать новый символ.

<textarea [(ngModel)]="textAreaContent" (keyup)="keyUp($event)">

component.ts:

Не ищите ключ ввода специально, так как код ключа может различаться в зависимости от устройства. Также это не поймало бы нежелательный символ, когда пользователь вставляет текст. Получите каждое нажатие клавиши и просто сделайте замену.

public textAreaContent;

keyUp(event:KeyboardEvent) {
  console.log(event.key+" pressed");
  this.textAreaContent = this.textAreaContent.replace(/[\r\n]+/," ");
}

Ответ 5

Используйте <input вместо <textarea и установите высоту как текстовое поле.

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