Reputation: 14179
Is it possible to ignore or not allow line breaks in a textarea in angularjs? The text is used in a pdf generator and I don't want the user to be able to type in a newline then not see it in the pdf. I would rather have the return key ignored all together.
<textarea ng-model="model.text"></textarea>
Upvotes: 12
Views: 10037
Reputation: 2609
Just an update for newer versions of Angular:
component.html:
Catch the keyup event, since at this point the bound variable will contain the new char.
<textarea [(ngModel)]="textAreaContent" (keyup)="keyUp($event)">
component.ts:
Don't look for the Enter key specifically, since the key code can vary between devices. Also that would not catch the unwanted char when user is pasting text. Get every keystroke, and just do a replace.
public textAreaContent;
keyUp(event:KeyboardEvent) {
console.log(event.key+" pressed");
this.textAreaContent = this.textAreaContent.replace(/[\r\n]+/," ");
}
Upvotes: 0
Reputation: 14179
Using Gísli Konráð and midhunsezhi answers I was able to put together a directive that did what I want. Credit should really go to them.
.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();
}
});
}
};
});
And it's used like this:
<textarea ng-model="text" no-new-lines></textarea>
Upvotes: 6
Reputation: 3591
Here's a directive that you could use. It has options to block invalid input and to ignore case.
.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();
}
});
}
}
};
});
You can see a demo of it here: https://jsfiddle.net/mr59xf3z/3/
Upvotes: 1
Reputation: 123937
Use <input
instead of <textarea
and set the height like textarea.
input.textarea {
height: 100px;
word-break: break-word;
width: 300px;
}
<input class="textarea">
Upvotes: -2
Reputation: 471
In your controller/directive if you run a regex to remove all the occurrences of '\n' in $scope.model.text
, you should get a plain string with no newline characters.
You can refer to this answer to do that: How to replace all occurrences of a string in JavaScript?
If you don't want even the text area to have any line breaks you can add the above logic in a watcher like this:
$scope.$watch('model.text', function(){
$scope.model.text = $scope.model.text.replace(/\n/g, '');
})
Upvotes: 7