How do I make a textarea an ACE editor?

As far as I understood the idea of Ace, you shouldn't make a textarea an Ace editor itself. You should create an additional div and update textarea using .getSession() function instead.

html

<textarea name="description"/>
<div id="description"/>

js

var editor = ace.edit("description");
var textarea = $('textarea[name="description"]').hide();
editor.getSession().setValue(textarea.val());
editor.getSession().on('change', function(){
  textarea.val(editor.getSession().getValue());
});

or just call

textarea.val(editor.getSession().getValue());

only when you submit the form with the given textarea. I'm not sure whether this is the right way to use Ace, but it's the way it is used on GitHub.


Duncansmart has a pretty awesome solution on his github page, progressive-ace which demonstrates one simple way to hook up an ACE editor to your page.

Basically we get all <textarea> elements with the data-editor attribute and convert each to an ACE editor. The example also sets some properties which you should customize to your liking, and demonstrates how you can use data attributes to set properties per element like showing and hiding the gutter with data-gutter.

// Hook up ACE editor to all textareas with data-editor attribute
$(function() {
  $('textarea[data-editor]').each(function() {
    var textarea = $(this);
    var mode = textarea.data('editor');
    var editDiv = $('<div>', {
      position: 'absolute',
      width: textarea.width(),
      height: textarea.height(),
      'class': textarea.attr('class')
    }).insertBefore(textarea);
    textarea.css('display', 'none');
    var editor = ace.edit(editDiv[0]);
    editor.renderer.setShowGutter(textarea.data('gutter'));
    editor.getSession().setValue(textarea.val());
    editor.getSession().setMode("ace/mode/" + mode);
    editor.setTheme("ace/theme/idle_fingers");

    // copy back to textarea on form submit...
    textarea.closest('form').submit(function() {
      textarea.val(editor.getSession().getValue());
    })
  });
});
textarea {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"></script>
<textarea name="my-xml-editor" data-editor="xml" data-gutter="1" rows="15"></textarea>
<br>
<textarea name="my-markdown-editor" data-editor="markdown" data-gutter="0" rows="15"></textarea>

You can have multiple Ace Editors. Just give each textarea an ID and create an Ace Editor for both IDS like so:

<style>
#editor, #editor2 {
    position: absolute;
    width: 600px;
    height: 400px;
}
</style>
<div style="position:relative; height: 450px; " >
&nbsp;
<div id="editor">some text</div>
</div>
<div style="position:relative; height: 450px; " >
&nbsp;
<div id="editor2">some text</div>
</div>
<script src="ace.js" type="text/javascript" charset="utf-8"></script>
<script src="theme-twilight.js" type="text/javascript" charset="utf-8"></script>
<script src="mode-xml.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/twilight");
    var XmlMode = require("ace/mode/xml").Mode;
    editor.getSession().setMode(new XmlMode());

    var editor2 = ace.edit("editor2");
    editor2.setTheme("ace/theme/twilight");
    editor2.getSession().setMode(new XmlMode());

};
</script>

To create an editor just do:

HTML:

<textarea id="code1"></textarea>
<textarea id="code2"></textarea>

JS:

var editor1 = ace.edit('code1');
var editor2 = ace.edit('code2');
editor1.getSession().setValue("this text will be in the first editor");
editor2.getSession().setValue("and this in the second");

CSS:

#code1, code2 { 
  position: absolute;
  width: 400px;
  height: 50px;
}

They must be explicitly positioned and sized. By show() and hide() I believe you are referring to the jQuery functions. I'm not sure exactly how they do it, but it cannot modify the space it takes up in the DOM. I hide and show using:

$('#code1').css('visibility', 'visible');
$('#code2').css('visibility', 'hidden');

If you use the css property 'display' it will not work.

Check out the wiki here for how to add themes, modes, etc... https://github.com/ajaxorg/ace/wiki/Embedding---API

Note: they do not have to be textareas, they can be whatever element you want.