Skip to content
Create a gist now

Instantly share code, notes, and snippets.

/* textarea auto-resize
* Based on implementation here:
* Hidden textarea technique inspired by:
* Stack Overflow version inspired by:
* 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.
* 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));
refresh: function()
// Update the shadow textarea and scroll to the bottom.
this._shadow.update($F(this.textarea).replace(/</g, '&lt;').replace(/&/g, '&amp;')).scrollTop = 10000;
// Do nothing if the scroll offset hasn't changed.
if(this._shadow.scrollTop == this.previous_scroll_top) { return; }
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
Something went wrong with that request. Please try again.