How do I make a textarea an ACE editor?
Asked Answered
W

5

99

I'd like to be able to convert specific textareas on a page to be ACE editors.

Does anyone have any pointers please?

EDIT:

I have the the editor.html file working with one textarea, but as soon as I add a second, the second isn't converted to an editor.

EDIT 2:

I decided to scrap the idea of having several, and instead open one up in a new window. My new predicament is that when I hide() and show() the textarea, the display goes awry. Any ideas?

Warm answered 22/6, 2011 at 13:12 Comment(1)
This guy has a pretty awesome solution: gist.github.com/duncansmart/5267653Caliginous
C
167

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.

Camarillo answered 2/11, 2011 at 11:43 Comment(6)
The textarea value should only be updated on form.submit event no? Also, according to this: groups.google.com/group/ace-discuss/browse_thread/thread/… There is no support for textarea replacement. Your answer is then the good one. Thx.Lodger
Sometimes you need to update a textarea value on the go, for example to implement draft auto save or so.Camarillo
I have a trouble with this method: texting 'SELECT 1 OR 2;' on ace.editor will put 'SELECT&nbsp;1OR&nbps;2;' to textarea. Can someone tell me what i'm doing wrong?Socman
alexglue, did you set white-space:nowrap on your textarea? github.com/ajaxorg/ace/issues/900Camarillo
Installero, i have no this css property on my textarea. So, no, i didn't.Socman
If you plan to update textarea live, be warned that your JS code may execute on every content change in Ace editor. Happened to me and destroyed the content just before saving. If you plan to allow JavaScript there, the best test is to execute console.log("test") inside script tags.Adamina
C
42

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>
Caliginous answered 22/10, 2013 at 9:1 Comment(3)
Highly recommended. Very flexible and clean!Kiwi
The only modification that I have made to the above code is changed textarea.css('visibility', 'hidden'); to textarea.css('display', 'none'); otherwise I was getting extra blank space on the screenCeramic
@NickGoloborodko - a couple years late here but I agree and I've updated the answer accordingly. Also, fixed the ace link so the snippet works again.Caliginous
R
8

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>
Rip answered 28/7, 2011 at 20:31 Comment(0)
G
1

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.

Guelph answered 19/9, 2011 at 23:20 Comment(1)
Except, no. If you invoke ace.edit('code1') you get garbage like: <textarea class="ace_editor ace-twilight ace_focus"><div class="ace_gutter">...</textarea> In otherwords the ace.edit tries to stuff itself inside textarea and this is not very nice.Scharf
W
1

For anyone that just wants a minimal, working example of using Ace from the CDN:

<!DOCTYPE html>
<html lang="en">

<body style="margin:0">
  <div id="editor">function () { 
  console.log('this is a demo, try typing!')
}
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js" type="text/javascript" charset="utf-8"></script>
  <script>
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");
    document.getElementById("editor").style.height = "120px";
  </script>
</body>

</html>
Wellknit answered 20/4, 2019 at 2:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.