Contao Textarea Autoheight with dummy

Puts textarea content in a dummy DIV to measure it.

by Andreas Burg

HTML

<div id="top" class="body">
  <div class="toggler">
    toggle wrap
    <img id="img" width="14" height="14" class="toggleWrap" alt="linewrap" src="http://demo.contao.org/system/themes/default/images/wrap.gif">
  </div>
  <textarea cols="80" rows="12" class="tl_textarea" id="ctrl_head" name="head">&lt;link rel="stylesheet" href="files/css/basic.css"&gt;
&lt;link rel="stylesheet" href="files/css/custom.css"&gt;
&lt;script src="files/js/misc.js"&gt;&lt;/script&gt;

This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text. This is one long line with text.</textarea>
</div>

CSS

.toggler {
  cursor: pointer;
  margin-bottom: 1em;
}
.toggleWrap {
  display: inline-block;  
}
.tl_textarea {
  resize: vertical;
  border: 1px solid #B8B8B8;
  border-radius: 3px;
  padding: 2px 3px;
  width: 676px;
  margin: 1px 0;
  font-size: 12px;
  color: #666966;
  font-family: "Trebuchet MS",Verdana,sans-serif;
}

JavaScript

// Textarea auto height
/** *
On Windows XP:
FF 25
Chrome 31.0
Opera 12.16
Safari 5.1.7
IE7/8
/** */
var
  textareas,
  areaWidth,
  height,
  contentDiv,
  textareaAutoHeight
;

textareas = $$('textarea');
contentDiv = Element('div.tl_textarea', {
  styles: {
    display: 'none',
    height: 'auto',
    lineHeight: 18,
    whiteSpace: 'pre-line',
    fontSize: 12,
    fontFamily: '"Trebuchet MS", Verdana, sans-serif',
    minHeight: 33
  }
});

textareaAutoHeight = function(area){
  areaWidth = area.getComputedSize().width;
  contentDiv.setStyle('width', areaWidth);
  contentDiv.set('text', area.value.replace(/\n/g, '\n.'));
  height = contentDiv.measure(function(){
    if(Browser.ie && Browser.version <= 8){
      return this.getComputedSize().height;
    }
    else {
      return getComputedStyle(contentDiv).height;
    }      
  });
  area.setStyle('height', height);
};

// Init
contentDiv.inject($('top'));
Array.each(textareas, function(item){
  item.setStyle('resize', 'vertical'); // This should be placed in regular css file
  textareaAutoHeight(item);
});

// Event listener (pause 250 is default without value in brackets)
if(Browser.ie && Browser.version <= 8){
  textareas.addEvent('keyup:pause(250)', function(){
    textareaAutoHeight(this);
  });
}
else {
  textareas.addEvent('input', function(){
    textareaAutoHeight(this);
  });
}

// Event for wrap toggler
$$('.toggler').addEvent('click', function(){
  $('ctrl_head').set('wrap', $('ctrl_head').get('wrap') == 'off' ? 'soft' : 'off');
});