Automatically adjust height to contents in Ace Cloud 9 editor

JavascriptAce Editor

Javascript Problem Overview


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()

Javascript Solutions


Solution 1 - Javascript

(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);
}

Solution 2 - Javascript

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

editor.setOptions({
    maxLines: 15
});

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

Solution 3 - Javascript

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)

Solution 4 - Javascript

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.

Solution 5 - Javascript

You can use jQuery:

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

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

Solution 6 - Javascript

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().

Solution 7 - Javascript

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();

Solution 8 - Javascript

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();
   };

Solution 9 - Javascript

I had the same problem but found out that it was so simple to automatically adjust the height by getting the height of its parent element and give it to the #editor and trigger a resize by editor.resize(). It just worked like a charm! bellow is the code i used:

let editor = ace.edit('editor'), $editorWrapper = $('.editor-wrapper');

$('#editor').height($editorWrapper.height());
 editor.resize();

Well, I did this when I was trying to toggle maximize feature on the editor.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlimitlessloopView Question on Stackoverflow
Solution 1 - JavascriptHostileFork says dont trust SEView Answer on Stackoverflow
Solution 2 - JavascriptDickeylthView Answer on Stackoverflow
Solution 3 - JavascriptCarl SmithView Answer on Stackoverflow
Solution 4 - JavascriptRené FernándezView Answer on Stackoverflow
Solution 5 - JavascriptJohnDoe DoeView Answer on Stackoverflow
Solution 6 - JavascriptAKFishView Answer on Stackoverflow
Solution 7 - JavascriptFabien SaView Answer on Stackoverflow
Solution 8 - JavascriptPaulView Answer on Stackoverflow
Solution 9 - JavascriptCodeparlView Answer on Stackoverflow