Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
fix(input, textarea): makes textarea autogrow optional, resolves #1209
Browse files Browse the repository at this point in the history
Fixes textarea auto grow inside scrollable container (resolves #2007 and possibly others)
Adds support for textarea auto grow based on rows attribute (resolves #2006)
Avoid "rows" attribute unintended overwrite by default value

Fixes #1209. Fixes #2007. Fixes #2006. Closes #3544.
  • Loading branch information
nantunes authored and ThomasBurleson committed Jul 2, 2015
1 parent 44b0ca0 commit 5fdcf90
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
57 changes: 51 additions & 6 deletions src/components/input/input.js
Expand Up @@ -110,6 +110,7 @@ function labelDirective() {
* The purpose of **`md-maxlength`** is exactly to show the max length counter text. If you don't want the counter text and only need "plain" validation, you can use the "simple" `ng-maxlength` or maxlength attributes.
* @param {string=} aria-label Aria-label is required when no label is present. A warning message will be logged in the console if not present.
* @param {string=} placeholder An alternative approach to using aria-label when the label is not present. The placeholder text is copied to the aria-label attribute.
* @param md-no-autogrow {boolean=} When present, textareas will not grow automatically.
*
* @usage
* <hljs lang="html">
Expand Down Expand Up @@ -230,7 +231,21 @@ function inputTextareaDirective($mdUtil, $window, $mdAria) {
}

function setupTextarea() {
if(angular.isDefined(element.attr('md-no-autogrow'))) {
return;
}

var node = element[0];
var container = containerCtrl.element[0];

var min_rows = NaN;
var lineHeight = null;
// can't check if height was or not explicity set,
// so rows attribute will take precedence if present
if(node.hasAttribute('rows')) {
min_rows = parseInt(node.getAttribute('rows'));
}

var onChangeTextarea = $mdUtil.debounce(growTextarea, 1);

function pipelineListener(value) {
Expand All @@ -245,19 +260,49 @@ function inputTextareaDirective($mdUtil, $window, $mdAria) {
onChangeTextarea();
}
element.on('keydown input', onChangeTextarea);
element.on('scroll', onScroll);

if(isNaN(min_rows)) {
element.attr('rows', '1');

element.on('scroll', onScroll);
}

angular.element($window).on('resize', onChangeTextarea);
element.attr('rows', '1');

scope.$on('$destroy', function() {
angular.element($window).off('resize', onChangeTextarea);
});

function growTextarea() {
node.style.height = "auto";
node.scrollTop = 0;
var height = getHeight();
if (height) node.style.height = height + 'px';
// sets the md-input-container height to avoid jumping around
container.style.height = container.offsetHeight + 'px';

// temporarily disables element's flex so its height 'runs free'
element.addClass('md-no-flex');

if(isNaN(min_rows)) {
node.style.height = "auto";
node.scrollTop = 0;
var height = getHeight();
if (height) node.style.height = height + 'px';
} else {
node.setAttribute("rows", 1);

if(!lineHeight) {
node.style.minHeight = '0';

lineHeight = element.height();

node.style.minHeight = null;
}

var rows = Math.max(min_rows, Math.round(node.scrollHeight / lineHeight));
node.setAttribute("rows", rows);
}

// reset everything back to normal
element.removeClass('md-no-flex');
container.style.height = 'auto';
}

function getHeight () {
Expand Down
4 changes: 4 additions & 0 deletions src/components/input/input.scss
Expand Up @@ -141,6 +141,10 @@ md-input-container {
outline: none;
box-shadow: none;
}

&.md-no-flex {
flex: none !important;
}
}

ng-messages, data-ng-messages, x-ng-messages,
Expand Down

2 comments on commit 5fdcf90

@alexitooi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thankyou 👍

@maggie9595
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Please sign in to comment.