Skip to content

Commit

Permalink
adding jquery.expandable.js
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonaaron committed Dec 23, 2008
0 parents commit 77b5be0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# expandable

A jQuery plugin that auto-expands textareas to fit the contents as a user types.


## Settings

The expandable plugin has 4 settings:

* `duration` - The speed of the animation when expanding (or shrinking). Default is 'normal'.
* `interval` - The interval at which it checks the textarea. Default is 750.
* `within` - The number of rows left before expanding. Default is 1.
* `by` - The number of rows to expand by. Default is 2.


## License

The expandable plugin is dual licensed *(just like jQuery)* under the [MIT](http://www.opensource.org/licenses/mit-license.php) and [GPL](http://www.opensource.org/licenses/gpl-license.php) licenses.

Copyright (c) 2008 [Brandon Aaron](http://brandonaaron.net)
43 changes: 43 additions & 0 deletions jquery.expandable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*/

(function($) {

$.fn.extend({
expandable: function(options) {
options = $.extend({ duration: 'normal', interval: 750, within: 1, by: 2 }, options);
return this.filter('textarea').each(function() {
var $this = $(this).css({ display: 'block', overflow: 'hidden' }), minHeight = $this.height(), interval, heightDiff = this.offsetHeight - minHeight,
rowSize = ( parseInt($this.css('lineHeight'), 10) || parseInt($this.css('fontSize'), 10) ),
$div = $('<div style="position:absolute;top:-999px;left:-999px;border-color:#000;border-style:solid;overflow-x:hidden;visibility:hidden;z-index:0;" />').appendTo('body');
$.each('borderTopWidth borderRightWidth borderBottomWidth borderLeftWidth paddingTop paddingRight paddingBottom paddingLeft fontSize fontFamily fontWeight fontStyle fontStretch fontVariant wordSpacing lineHeight width'.split(' '), function(i,prop) {
$div.css(prop, $this.css(prop));
});
$this
.bind('keypress', function(event) { if ( event.keyCode == '13' ) check(); })
.bind('focus blur', function(event) {
if ( event.type == 'blur' ) clearInterval( interval );
if ( event.type == 'focus' && !interval ) setInterval(check, options.interval);
});
function check() {
var text = $this.val(), newHeight, height, usedHeight, usedRows, availableRows;
$div.html( text.replace(/\n/g, '&nbsp;<br>') );
height = $this[0].offsetHeight - heightDiff;
usedHeight = $div[0].offsetHeight - heightDiff;
usedRows = Math.floor(usedHeight / rowSize);
availableRows = Math.floor((height / rowSize) - usedRows);
if ( availableRows <= options.within ) {
newHeight = rowSize * (usedRows + Math.max(availableRows, 0) + options.by);
$this.stop().animate({ height: newHeight }, options.duration);
} else if ( availableRows > options.by + options.within ) {
newHeight = Math.max( height - (rowSize * (availableRows - (options.by + options.within))), minHeight )
$this.stop().animate({ height: newHeight }, options.duration);
}
};
}).end();
}
});

})(jQuery);

0 comments on commit 77b5be0

Please sign in to comment.