phorsfall (owner)

Revisions

gist: 195495 Download_button fork
public
Public Clone URL: git://gist.github.com/195495.git
Embed All Files: show embed
textarea-auto-resize.js #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* 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, '&lt;').replace(/&/g, '&amp;')).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;
  }
});