Created
September 28, 2009 15:16
-
-
Save phorsfall/195495 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Nurphy.com textarea auto-resize | |
* | |
* Based on implementation here: | |
* http://stackoverflow.com/questions/7477/autosizing-textarea | |
* | |
* Hidden textarea technique inspired by: | |
* http://james.padolsey.com/javascript/jquery-plugin-autoresize/ | |
* | |
* Stack Overflow version inspired by: | |
* http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js | |
* | |
* Notes: | |
* | |
* This will probably need the height of the textarea to be specified in | |
* pixels via CSS to work in IE. This is because we need to fetch the original | |
* height of the textarea in pixels, and according to the documentation | |
* getStyle('height') will return the actual (rather than computed) value in | |
* IE, which will be in whatever units the style was set in. | |
* | |
* http://www.prototypejs.org/api/element/getStyle | |
* | |
* Using getHeight() which should return the height in pixels returned | |
* different results across Safari and Firefox in testing. | |
* | |
*-------------------------------------------------------------------------- */ | |
if (window.Widget == undefined) window.Widget = {}; | |
Widget.Textarea = Class.create({ | |
initialize: function(textarea, options) | |
{ | |
this.textarea = $(textarea); | |
this.options = $H({ }).update(options); | |
// Disable scroll bars and Safari resizing. | |
this.textarea.setStyle({ overflowY: 'hidden', resize: 'none' }); | |
// See notes above. | |
this.original_height = parseInt(this.textarea.getStyle('height')); | |
// Used to store the scroll offset of the shadow textarea so that we only | |
// need to do a resize if there's a change to this value. | |
this.previous_scroll_top = 0; | |
// Clone the textarea and copy any styles that will affect the amount of | |
// space consumed by text. | |
this._shadow = this.textarea.cloneNode(false).setStyle({ | |
lineHeight: this.textarea.getStyle('lineHeight'), | |
fontSize: this.textarea.getStyle('fontSize'), | |
fontFamily: this.textarea.getStyle('fontFamily'), | |
letterSpacing: this.textarea.getStyle('letterSpacing'), | |
width: this.textarea.getStyle('width'), | |
height: this.textarea.getStyle('height'), | |
position: 'absolute', | |
top: '-10000px', | |
left: '-10000px' | |
}).writeAttribute({ id: null, name: null, disabled: true }); | |
this.textarea.insert({ after: this._shadow }); | |
// Could also fire on keydown, but I don't have a strong enough reason to | |
// do so at present. We'd be doubling the number of calls to refresh(). | |
this.textarea.observe('keyup', this.refresh.bind(this)); | |
this.textarea.observe('change', this.refresh.bind(this)); | |
this.refresh(); | |
}, | |
refresh: function() | |
{ | |
// Update the shadow textarea and scroll to the bottom. | |
this._shadow.update($F(this.textarea).replace(/</g, '<').replace(/&/g, '&')).scrollTop = 10000; | |
// Do nothing if the scroll offset hasn't changed. | |
if(this._shadow.scrollTop == this.previous_scroll_top) { return; } | |
this.textarea.setStyle({ | |
height: (this._shadow.scrollTop + this.original_height) + 'px' | |
}); | |
this.previous_scroll_top = this._shadow.scrollTop; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment