¿Cómo puedo convertir un área de texto en un editor ACE?

96

Me gustaría poder convertir áreas de texto específicas en una página para que sean editores ACE.

¿Alguien tiene algún consejo, por favor?

EDITAR:

Tengo el archivo editor.html funcionando con un área de texto, pero tan pronto como agrego un segundo, el segundo no se convierte en un editor.

EDITAR 2:

Decidí descartar la idea de tener varios y, en su lugar, abrir uno en una nueva ventana. Mi nuevo problema es que cuando oculto () y muestro () el área de texto, la pantalla sale mal. ¿Algunas ideas?

Pablo
fuente
1
Este tipo tiene una solución bastante impresionante: gist.github.com/duncansmart/5267653
billynoah

Respuestas:

159

Por lo que entendí la idea de Ace, no deberías convertir un área de texto en un editor de Ace. Debería crear un div adicional y actualizar textarea usando la función .getSession () en su lugar.

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

o simplemente llama

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

solo cuando envíe el formulario con el área de texto dada. No estoy seguro de si esta es la forma correcta de usar Ace, pero es la forma en que se usa en GitHub .

installero
fuente
1
El valor del área de texto solo debe actualizarse en form.submit event no? Además, de acuerdo con esto: groups.google.com/group/ace-discuss/browse_thread/thread/… No hay soporte para el reemplazo del área de texto. Entonces tu respuesta es la buena. Gracias.
Damien
4
A veces es necesario actualizar un valor de área de texto sobre la marcha, por ejemplo, para implementar el guardado automático de borradores o algo así.
installero
Tengo un problema con este método: enviar un mensaje de texto con 'SELECT 1 OR 2;' en ace.editor pondrá 'SELECT&nbsp;1OR&nbps;2;'a textarea. ¿Alguien puede decirme qué estoy haciendo mal?
alexglue
alexglue, ¿estableciste white-space: nowrap en tu área de texto? github.com/ajaxorg/ace/issues/900
installero
Installero, no tengo esta propiedad css en mi área de texto. Entonces, no, no lo hice.
alexglue
33

Duncansmart tiene una solución bastante impresionante en su página de github, progress-ace, que demuestra una forma sencilla de conectar un editor ACE a su página.

Básicamente, obtenemos todos los <textarea>elementos con el data-editoratributo y convertimos cada uno en un editor ACE. El ejemplo también establece algunas propiedades que debe personalizar a su gusto y demuestra cómo puede usar dataatributos para establecer propiedades por elemento, como mostrar y ocultar el canalón 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>

Billynoah
fuente
3
Muy recomendable. ¡Muy flexible y limpio!
aaandre
5
La única modificación que he realizado al código anterior es textarea.css ('visibilidad', 'oculto'); a textarea.css ('mostrar', 'ninguno'); de lo contrario, estaba obteniendo espacio en blanco adicional en la pantalla
Nick Goloborodko
@NickGoloborodko: un par de años tarde aquí, pero estoy de acuerdo y he actualizado la respuesta en consecuencia. Además, se corrigió el enlace ace para que el fragmento funcione nuevamente.
billynoah
@billynoah Usé este código pero lo que tengo es un espacio en blanco que no se puede editar, ¿cómo puedo solucionar esto? Gracias
bleyk
no tengo idea, claramente no usó este código exactamente como está o habría funcionado, tal como lo hace el fragmento. si necesita ayuda para depurar, debe comenzar una nueva pregunta.
billynoah
8

Puede tener varios Ace Editors. Simplemente dé a cada área de texto una ID y cree un Ace Editor para ambos IDS así:

<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>
Breck
fuente
1

Para crear un editor, simplemente haga lo siguiente:

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

Deben colocarse y dimensionarse explícitamente. Por show () y hide () creo que se está refiriendo a las funciones jQuery. No estoy seguro de cómo lo hacen exactamente, pero no puede modificar el espacio que ocupa en el DOM. Me escondo y muestro usando:

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

Si usa la propiedad css 'display', no funcionará.

Consulte la wiki aquí para saber cómo agregar temas, modos, etc. https://github.com/ajaxorg/ace/wiki/Embedding---API

Nota: no tienen que ser áreas de texto, pueden ser cualquier elemento que desee.

Poli
fuente
8
Excepto que no. Si invocas ace.edit('code1'), obtienes basura como: <textarea class="ace_editor ace-twilight ace_focus"><div class="ace_gutter">...</textarea>En otras palabras, ace.edit intenta meterse dentro de textarea y esto no es muy agradable.
Ciantic
0

Para cualquiera como yo que solo quiera un ejemplo mínimo y funcional del uso de Ace de la 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>

Nic Scozzaro
fuente
Veo que alguien votó negativamente ... ¿no funcionó para usted?
Nic Scozzaro