Reputation: 1069
I'm attempting to create a line numbering system for a textarea
element using Angular's ng-repeat
directive. Essentially, using the ng-keyup
event, I'm calling a function updateLineNumbers()
that calculates the total amount of lines in the textarea
and adds to an array of line numbers attached to the $scope
if needed.
angular.module('editorApp')
.controller('LineNumberController', ['$scope', function($scope){
$scope.lines = [1];
$scope.updateLineNumber = function(){
var text = $("#editor").val();
var lines = text.split(/\r|\r\n|\n/);
var count = lines.length;
console.log(count);
if(count > $scope.lines.length){
console.log("adding line...");
var len = $scope.lines.length;
var linesToAdd = count - len;
console.log("lines to add: " + linesToAdd);
for(var i = 0; i < linesToAdd; i++){
console.log('adding line number: ' + (i + $scope.lines[len - 1] + 1));
$scope.lines.push(i + $scope.lines[len - 1] + 1);
}
}
}
}]);
The console log statements are just for debugging purposes btw. This works fine, and everything displays how i want it, however I notice its just slightly slow. The new line number appears just a moment behind the cursor making it to the next line. I know its picky, but this bothers me and I was wondering if there was a solution for this in Angular, or if I should just use JQuery.
Here is the html code:
<div class="main-editor" ng-controller="LineNumberController">
<div class="line-numbers">
<div ng-repeat="line in lines" id="line{{ $index + 1 }}">{{ $index + 1 }}</div>
</div>
<div class="editor-container">
<textarea name="editor" id="editor" cols="30" rows="10" ng-keyup="updateLineNumber()"></textarea>
</div>
</div>
Here's the plunkr http://plnkr.co/edit/0POJTx0p4rtfwOAaNRPb?p=preview
Upvotes: 0
Views: 375
Reputation: 171669
Here's a simpler approach using a watch on ng-model
The important part is using ng-trim="false"
otherwise ng-model
will trim breaks after last character
var lineCount = 1;
$scope.$watch('model.editor', function(nV, oV) {
if (!nV) {
$scope.lines = [1];
} else {
var lines = nV.split(/\r|\r\n|\n/);
// create new array if number of lines changed
if (lines.length !== lineCount) {
$scope.lines = lines.map(function(_, i) {
return i + 1
});
lineCount = lines.length;
}
}
});
View
<div class="line-numbers">
<div ng-repeat="line in lines" id="line{{ $index + 1 }}">{{ line }}</div>
</div>
<div class="editor-container">
<textarea name="editor" id="editor" cols="30" rows="10" ng-model="model.editor" ng-trim="false"></textarea>
</div>
Note this works also while removing data.
Upvotes: 1