Comment faire d'une zone de texte un éditeur ACE?

96

J'aimerais pouvoir convertir des zones de texte spécifiques sur une page en éditeurs ACE.

Quelqu'un at-il des conseils s'il vous plaît?

ÉDITER:

J'ai le fichier editor.html fonctionnant avec une zone de texte, mais dès que j'ajoute une seconde, la seconde n'est pas convertie en éditeur.

MODIFIER 2:

J'ai décidé d'abandonner l'idée d'en avoir plusieurs et d'en ouvrir une dans une nouvelle fenêtre. Ma nouvelle situation est que lorsque je cache () et montre () la zone de texte, l'affichage tourne mal. Des idées?

Paul
la source
1
Ce gars a une solution assez géniale: gist.github.com/duncansmart/5267653
billynoah

Réponses:

159

Autant que j'ai compris l'idée d'Ace, vous ne devriez pas faire d'une zone de texte un éditeur Ace lui-même. Vous devez créer un div supplémentaire et mettre à jour textarea en utilisant .getSession () place.

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

ou juste appeler

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

uniquement lorsque vous soumettez le formulaire avec la zone de texte donnée. Je ne sais pas si c'est la bonne façon d'utiliser Ace, mais c'est la façon dont il est utilisé sur GitHub .

installero
la source
1
La valeur textarea ne doit être mise à jour que lors de l'événement form.submit no? En outre, selon ceci: groups.google.com/group/ace-discuss/browse_thread/thread/… Il n'y a pas de support pour le remplacement de textarea. Votre réponse est alors la bonne. THX.
Damien
4
Parfois, vous devez mettre à jour une valeur de zone de texte lors de vos déplacements, par exemple pour implémenter une sauvegarde automatique du brouillon.
installero
J'ai un problème avec cette méthode: envoyer un SMS 'SELECT 1 OR 2;' sur ace.editor mettra 'SELECT&nbsp;1OR&nbps;2;'à textarea. Quelqu'un peut-il me dire ce que je fais mal?
alexglue
alexglue, avez-vous mis un espace blanc: nowrap sur votre zone de texte? github.com/ajaxorg/ace/issues/900
installero
Installero, je n'ai pas cette propriété css sur mon textarea. Alors, non, je ne l'ai pas fait.
alexglue
33

Duncansmart a une solution assez géniale sur sa page github, progressive-ace qui montre un moyen simple de connecter un éditeur ACE à votre page.

Fondamentalement, nous obtenons tous les <textarea>éléments avec l' data-editorattribut et les convertissons chacun en éditeur ACE. L'exemple définit également certaines propriétés que vous devez personnaliser à votre guise et montre comment vous pouvez utiliser des dataattributs pour définir des propriétés par élément, comme afficher et masquer la gouttière 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
la source
3
Hautement recommandé. Très flexible et propre!
aaandre
5
La seule modification que j'ai apportée au code ci-dessus est celle de textarea.css ('visibilité', 'hidden'); à textarea.css ('afficher', 'aucun'); sinon, je
recevais
@NickGoloborodko - quelques années de retard ici mais je suis d'accord et j'ai mis à jour la réponse en conséquence. En outre, correction du lien as pour que l'extrait fonctionne à nouveau.
billynoah
@billynoah J'ai utilisé ce code mais ce que j'ai est un espace vide qui ne peut pas être édité, comment puis-je résoudre ce problème? Merci
bleyk
Je n'ai aucune idée, il est clair que vous n'avez pas utilisé ce code exactement tel quel ou cela aurait fonctionné - tout comme l'extrait de code le fait. si vous avez besoin d'aide pour le débogage, vous devez commencer une nouvelle question.
billynoah
8

Vous pouvez avoir plusieurs éditeurs Ace. Donnez simplement à chaque zone de texte un identifiant et créez un éditeur Ace pour les deux IDS comme ceci:

<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
la source
1

Pour créer un éditeur, faites simplement:

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

Ils doivent être explicitement positionnés et dimensionnés. Par show () et hide (), je crois que vous faites référence aux fonctions jQuery. Je ne sais pas exactement comment ils le font, mais cela ne peut pas modifier l'espace qu'il prend dans le DOM. Je cache et montre en utilisant:

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

Si vous utilisez la propriété css 'display', cela ne fonctionnera pas.

Consultez le wiki ici pour savoir comment ajouter des thèmes, des modes, etc. https://github.com/ajaxorg/ace/wiki/Embedding---API

Remarque: ils ne doivent pas nécessairement être des zones de texte, ils peuvent être l'élément de votre choix.

Policier
la source
8
Sauf que non. Si vous invoquez, ace.edit('code1')vous obtenez des déchets comme: <textarea class="ace_editor ace-twilight ace_focus"><div class="ace_gutter">...</textarea>En d'autres termes, ace.edit essaie de se bourrer dans textarea et ce n'est pas très agréable.
Ciantic
0

Pour tous ceux comme moi qui veulent juste un exemple minimal et fonctionnel d'utilisation d'Ace à partir du 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
la source
Je vois quelqu'un qui a voté contre ... cela n'a pas fonctionné pour vous?
Nic Scozzaro