omer
omer

Reputation: 2623

textarea height equel to scrollheight flow issue

I wrote this simple function, and it's working fine but I'm trying to make it a little bit better.

I have a textarea that resizes when the scroll height changes, the thing is that when I hit enter (i.e line down - \n) there is a jump in the height as it updates because the scroll height updates only after text is entered.

For now I've solved it with css overflow:hidden but its not perfect... I've tried to catch the enter event as well but it was problematic because the height changes too quickly...

Here is a jsfiddle which the code in question.

JS:

var app = angular.module('myModule', []);

app.controller('myCtrl', function ($scope, $timeout) {



    $scope.ModelData = "";

    $scope.modelScrollHeight = document.getElementById('textareaId').scrollHeight;

    $scope.getScrollHeight = function(){
     $scope.modelScrollHeight  = document.getElementById('textareaId').scrollHeight;;
     return  $scope.modelScrollHeight;
    }


});

HTML:

<div ng-controller = "myCtrl"> 
  <div class="omeromer" style="" >
    <textarea
        ng-style="{'min-height':(!ModelData || ModelData.trim() === '') ? '40px' :  modelScrollHeight+'px'}"
        style="border: none;resize:none;border-color: #EFEFEF; " 
       ng-model="ModelData" ng-change="getScrollHeight()" id="textareaId" class="wm-noteList-text-overflow"
        > </textarea>
    <pre>"val: "{{ModelData|json}}</pre>
    <pre>"split "{{ModelData.split('\n').length - 1|json}}</pre>
    <pre>"length: "{{ModelData.length|json}}</pre>
     <pre>"scrollHeight: "{{modelScrollHeight|json}}</pre>


</div>

</div>

CSS:

.wm-noteList-text-overflow{

    width:200px;
    //overflow:hidden;
}

Upvotes: 1

Views: 532

Answers (2)

coma
coma

Reputation: 16639

What about putting the resizing function in angular's internal $formatters array?

A jsfiddle

app.directive('autoHeight', function () {

  return {
    require : '?ngModel',
    restrict: 'A',
    link    : function (scope, element, attrs, ngModel) {

      var node = element[0];

      function refresh () {

        node.style.height = null;
        node.style.height = node.scrollHeight + 'px';
      }

      if (ngModel) {

        ngModel.$formatters.push(function (value) {

          refresh();

          return value;
        });
      }

      element.on('input', refresh);
      refresh();
    }
  };
});

Upvotes: 1

Dexter
Dexter

Reputation: 2472

Have you tried adding ng-trim=false to the textarea? It seems to do the trick.

Otherwise, a similar question was asked here, I recommend trying some of the solutions proposed there.

Upvotes: 1

Related Questions