3
votes

How do I insert a tab character (indent) inside a textarea using AngularJS?

I tried this:

<textarea class="form-control" rows="10" ng-model="vm.text" ng-keydown="vm.handleTabKey($event)"></textarea>

With function handleTabKey being:

function handleTabKey(e) {
  if (e.which === 9) {
    e.preventDefault();
    var start = e.target.selectionStart;
    var end = e.target.selectionEnd;
    vm.text = vm.text.substring(0, start) + '\t' + vm.text.substring(end);
    e.target.selectionStart = e.target.selectionEnd = start + 1;
  }
};

Although the tab character is inserted, the caret position is always at the end, despite the last line.

Another problem is that if I insert one or more new lines at the end, pressing tab will insert a tab at the end of the line before the new lines, as if ignoring them. In other words, vm.text doesn't contain those new lines until non-whitespace characters are entered.

2

2 Answers

2
votes

By default, ngModel will trim white space at the end unless you use ng-trim="false".

Source: https://github.com/angular/angular.js/issues/2010

Regarding the cursor position, I think you need to target the element and use .setSelectionRange() instead.

UPDATE

Based on your JSFiddle, I was able to set the cursor position using this instead:

angular.element(e.target).val(vm.text.substring(0, start) + '\t' + vm.text.substring(end));

Working JSFiddle: https://jsfiddle.net/7bee7nuc/2/

UPDATE 2

The previous snippet couldn't insert consecutive tab characters. To do this, vm.text must be updated as well as the target element.

Updated JSFiddle: https://jsfiddle.net/7bee7nuc/3/

0
votes

Have a look at my pen, it could accept formatting text with tab or shift tab character on a single line or multiple line just like a text editor. It has no need to any other JS library.