Question

I'm trying to add the Ace editor to a page, but I don't know how to get the height to be set automatically based on the length of its contents.

Ideally it would work so when the content changes the height is recalculated, but I would be happy with the height just being set on page load.

For a JavaScript novice can someone help me figure out how I work out the length of the code, how many lines it spans, what the new height is and how I update the DOM to reflect this?

I found this suggestion in a Google group, but I don't really understand what it's doing and how I get it to adjust the height.

editor.getSession().getDocument().getLength() *
editor.renderer.lineHeight + editor.renderer.scrollBar.getWidth()
Was it helpful?

Solution

(UPDATE: I'm not working with this at the moment, but my answer may be out of date. To try and incorporate what others have provided, I'll echo their mention of the minLines and maxLines properties, e.g.

editor.setOptions({
    maxLines: Infinity
});

Apparently infinity is "not a very good idea, since it will disable virtual viewport even for very large documents." So picking a limit may be better.

For history's sake, the old answer was:


The post you cite is just operating on the assumption that it's a fixed width font whose character height you know, and that you know the number of lines in the document. Multiply that together you get a pixel count for how tall the content is. The suggestion is that every time a character is pressed or a cut/paste happens (which may add or remove lines), you use JavaScript to apply this concrete new size to the items in your DOM with CSS styles.

(They throw in the "width" of a scrollbar into a height calculation, and I honestly can't tell you if there's a rationale behind that or not. I'll let someone else figure that part out.)

Anyway...if you have soft wrap on, the number of rendered screen lines spanned may be more than the number of "actual" lines in the document. So it is better to use editor.getSession().getScreenLength() than editor.getSession().getDocument().getLength().

I put the editor (position: absolute) inside of a section (position: relative), and it's the only item living in that section. This code is seemingly working for me for now, I'll update it if I learn more...!

$(document).ready(function(){

    var heightUpdateFunction = function() {

        // http://stackoverflow.com/questions/11584061/
        var newHeight =
                  editor.getSession().getScreenLength()
                  * editor.renderer.lineHeight
                  + editor.renderer.scrollBar.getWidth();

        $('#editor').height(newHeight.toString() + "px");
        $('#editor-section').height(newHeight.toString() + "px");

        // This call is required for the editor to fix all of
        // its inner structure for adapting to a change in size
        editor.resize();
    };

    // Set initial size to match initial content
    heightUpdateFunction();

    // Whenever a change happens inside the ACE editor, update
    // the size again
    editor.getSession().on('change', heightUpdateFunction);
}

OTHER TIPS

Ace provides an option: maxLines so that you can simply try:

editor.setOptions({
    maxLines: 15
});

http://jsfiddle.net/cirosantilli/9xdkszbz/

Update: See Dickeylth's answer. This all still works (and people still seem to find it useful), but the basic functionality is built into ACE now.


To "automatically adjust height to contents in Ace Cloud9 editor", you just need to resize the editor to fit the div that contains it, whenever the content is edited. Assuming you started with <div id=editor>...

var editor = ace.edit("editor");                   // the editor object
var editorDiv = document.getElementById("editor");     // its container
var doc = editor.getSession().getDocument();  // a reference to the doc

editor.on("change", function() {
    var lineHeight = editor.renderer.lineHeight;
    editorDiv.style.height = lineHeight * doc.getLength() + "px";
    editor.resize();
});

You resize the div the editor lives in, then call editor.resize to get the editor to refill the div.

If you paste content with long lines, with ACE set to wrap lines, the number of new lines and actual rendered lines will differ, so the editor will scroll. This code will fix that, but you will get horizontal scrolling instead.

editor.getSession().setUseWrapMode(false)

I think that a solution might be counting the number of lines in the editor and then resize it to fit these lines:

editor.setOptions({
     maxLines: editor.session.getLength()
});

Hope this helps.

You can use jQuery:

 var length_editor = editor.session.getLength();
 var rows_editor = length_editor * 17;

 $('#editor').css('height',rows_editor);

I agree with the accepted answer, except that I would prefer editor.getSession().getScreenLength().

The issue is that if you enable wrap mode, a long line may break into multiple lines. Thus you will not be able to get correct line count with editor.getSession().getDocument().getLength().

This variant works better for me as sometimes the editor.renderer.lineHeight returns 1

    var resize = function() {
     var minHt = 16;
     var sl = editor.getSession().getScreenLength();
     var sw = editor.renderer.scrollBar.getWidth();
     var lh = Math.max(editor.renderer.lineHeight, minHt);
     var ht = Math.max(((sl * lh) + sw), minHt);
     $('#myEditorDiv').height(ht);
     editor.resize();
   };

My method in pure JavaScript (replace editor-container with the right id).

function adaptEditor() {
    document.getElementById('editor-container').style.height = window.innerHeight + 'px';
    editor.resize();
}
window.onresize = function(event) {
    adaptEditor();
};
adaptEditor();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top