I have a textarea that allows users to input up to 16 lines of text. I created a directive for this purpose, and it works well when the user hits the enter key.
However, I also want to restrict the input to only 16 lines, even if the user enters a very long text that wraps into multiple lines without hitting enter.
The reason behind this question is that I have a digital postcard where users can add a personalized message. The postcard has fixed dimensions, so the textarea should reflect these dimensions by limiting the text to no more than 16 lines.
Is it possible to achieve this using JavaScript?
Here is my current code:
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);
}
};
});