I have a textarea which allows users to put in 16 lines. I've build an directive for that purpose, and everything works fine, if the user hits enter.
But I also want to prevent more than 16 lines, even if the user does not hit enter, but puts in a very long text, which is displayed into multiple lines (forced line break).
The background of this question is the following: I have a postcard, and users should be able to enter text to this postcard. The postcard has a fixed width/height. The textarea should represent the fixed width/height of the postcard, so users can see how many space they have left to fill out the postcard (not more than 16 lines).
Is this possible with JS?
My code so far:
HTML
<textarea placeholder="Enter text" rows="16" ng-trim="false" id="message-textarea" maxlines="16" maxlines-prevent-enter="true"></textarea>
JS Directive
app.directive('maxlines', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) {
var maxLines = 1;
attrs.$observe('maxlines', function(val) {
maxLines = parseInt(val);
});
ngModel.$validators.maxlines = function(modelValue, viewValue) {
var numLines = (modelValue || '').split("\n").length;
var diffLines = maxLines - numLines;
scope.$emit('cliked-from-directive-maxlines', {diffLines});
return numLines <= maxLines;
};
attrs.$observe('maxlinesPreventEnter', function(preventEnter) {
// if attribute value starts with 'f', treat as false. Everything else is true
preventEnter = (preventEnter || '').toLocaleLowerCase().indexOf('f') !== 0;
if (preventEnter) {
addKeypress();
} else {
removeKeypress();
}
});
function addKeypress() {
elem.on('keypress', function(event) {
// test if adding a newline would cause the validator to fail
if (event.keyCode == 13 && !ngModel.$validators.maxlines(ngModel.$modelValue + '\n', ngModel.$viewValue + '\n')) {
event.preventDefault();
}
});
}
function removeKeypress() {
elem.off('.maxlines');
}
scope.$on('$destroy', removeKeypress);
}
};
});