2011-12-01 10 views
56

Sto utilizzando codemirror 2 e funziona bene, tranne che il valore impostato dell'editor non viene caricato nell'editor finché non faccio clic sull'editor e diventa attivo.L'editor di codemirror non carica il contenuto fino a quando non si fa clic

Voglio che l'editor mostri il contenuto di se stesso senza che debba essere fatto clic. Qualche idea?

Tutte le demo di codemirror funzionano come previsto, quindi ho pensato che forse la textarea non è focalizzata, quindi ho provato anche quello.

$("#editor").focus(); 
var editor = CodeMirror.fromTextArea(document.getElementById("editor"), { 
        mode: "text/html", 
        height: "197px", 
        lineNumbers: true 
       }); 
+2

Ho anche questo problema, dove carico un editor CodeMirror su un popup modale. Hai trovato una soluzione su come mettere a fuoco l'editor? Grazie. –

risposta

31

Devi chiamare refresh() dopo setValue(). Tuttavia, è necessario utilizzare setTimeout di rinviare il refresh() per dopo CodeMirror/Browser ha aggiornato il layout in base al nuovo contenuto:

this.codeMirrorInstance.setValue(content); 
var that = this; 
setTimeout(function() { 
    that.codeMirrorInstance.refresh(); 
},1); 

Funziona bene per me. Ho trovato la risposta in here.

+1

Ho avuto lo stesso problema con le schede dell'interfaccia utente jQuery e mi aiuta. – greenif

0

Provare a chiamare focus sull'elemento DOM anziché sull'oggetto jQuery.

var editor=$('#editor'); 
editor[0].focus(); 
// or 
document.getElementById('editor').focus(); 
+0

Grazie per la risposta, ho intenzione di provarlo. – Karl

23

mi aspetto che tu (o qualche script è stato caricato) è ingerenza con il DOM in modo tale che l'editor è nascosta o comunque in una strana posizione al momento della creazione. Richiede una chiamata al suo metodo refresh() dopo che è stato reso visibile.

+0

Grazie per la risposta, ho intenzione di provare anche quello. – Karl

+2

Nella mia implementazione, l'oggetto genitore ha iniziato 'display: none;' che ha causato questo problema- questa risposta ha risolto il problema facilmente! Grazie, @ Marjn! – Soleil

+0

Questo ha risolto anche il mio caso in cui l'elemento padre è GWT TabLayoutPanel o DisclosurePanel che attiva/disattiva la visualizzazione dei propri figli. L'ho risolto usando listener su questi pannelli principali e rimandando un aggiornamento del mirror del codice quando lo mostravo. – jolivier

0

Questa sera mi sono imbattuto in una versione di questo problema.

Un numero di altri post considera importante la visibilità del textarea del genitore, se è nascosto, è possibile imbattersi in questo problema.

Nella mia situazione il modulo stesso e l'ambiente circostante andavano bene, ma il mio view manager Backbone più in alto nella catena di rendering era il problema.

Il mio elemento di vista non è posizionato sul DOM finché la vista non si è completamente renderizzata, quindi suppongo che un elemento non sul DOM sia considerato nascosto o semplicemente non gestito.

Per aggirare l'ostacolo ho aggiunto un-renderizzare fase post (pseudocodice):

view.render(); 
$('body').html(view.el); 
view.postRender(); 

Nel postRender la vista può fare quello che deve sapere che tutto il contenuto è ora visibile sullo schermo, è qui Ho spostato il CodeMirror e ha funzionato bene.

Questo potrebbe anche spiegare in parte il motivo per cui ci si può imbattere in problemi con elementi come i popup in quanto in alcuni casi potrebbero tentare di creare tutto il contenuto prima di essere visualizzati.

La speranza che aiuta qualcuno.

Toby

1

Un'altra soluzione (che ho capito anche perché l'editor doveva essere visibile per creare correttamente) è di collegare temporaneamente l'elemento genitore all'elemento body durante la costruzione, quindi ricollegare una volta completato.

In questo modo, non è necessario intromettersi con gli elementi o preoccuparsi della visibilità in qualsiasi gerarchia esistente che il tuo editor potrebbe essere sepolto.

Nel mio caso, per processr.com, ho più, elementi di editing del codice nidificati, i quali devono essere creati al volo, come l'utente effettua aggiornamenti, così faccio la seguente:

this.$elements.appendTo('body'); 
for (var i = 0; i < data.length; i++) 
{ 
    this.addElement(data[i]); 
} 
this.$elements.appendTo(this.$view); 

E ' funziona alla grande, e non c'è stato alcun sfarfallio visibile o qualcosa del genere finora.

+0

Bella soluzione. grazie – rgomesf

5

Qualcosa ha funzionato per me.

$(document).ready(function(){ 
       var editor = CodeMirror.fromTextArea(document.getElementById("code2"), { 
        //lineNumbers: true, 
         readOnly: true, 
         autofocus: true, 
        matchBrackets: true, 
        styleActiveLine: true 
       }); 
       setTimeout(function() { 
        editor.refresh(); 
        }, 100); 

     }); 
0
<div class="tabbable-line"> 
    <ul class="nav nav-tabs"> 
     <li class="active"> 
      <a href="#tabXml1" data-toggle="tab" aria-expanded="true">Xml 1</a> 
     </li> 
     <li class=""> 
      <a href="#tabXml2" id="xmlTab2Header" data-toggle="tab" aria-expanded="true">Xml 2</a> 
     </li> 
    </ul> 
    <div class="tab-content"> 
     <div class="tab-pane active" id="tabXml1"> 
      <textarea id="txtXml1" /> 
     </div> 
     <div class="tab-pane" id="tabXml2"> 
      <textarea id="txtXml2" /> 
     </div> 
    </div> 
</div> 

<link rel="stylesheet" href="~/Content/codemirror.min.css"> 
<style type="text/css"> 
    .CodeMirror { 
     border: 1px solid #eee; 
     max-width: 100%; 
     height: 400px; 
    } 
</style> 

<script src="~/Scripts/codemirror.min.js"></script> 
<script src="~/Scripts/codemirror.xml.min.js"></script> 
<script> 
     $(document).ready(function() { 
      var cmXml1; 
      var cmXml2; 
      cmXml1 = CodeMirror.fromTextArea(document.getElementById("txtXml1"), { 
       mode: "xml", 
       lineNumbers: true 
      }); 
      cmXml2 = CodeMirror.fromTextArea(document.getElementById("txtXml2"), { 
       mode: "xml", 
       lineNumbers: true 
      }); 
      // Refresh code mirror element when tab header is clicked. 
      $("#xmlTab2Header").click(function() { 
       setTimeout(function() { 
        cmXml2.refresh(); 
       }, 10); 
      }); 
     }); 
</script> 
1

Qualcosa ha funzionato per me! :)

 var sh = setInterval(function() { 
     agentConfigEditor.refresh(); 
     }, 500); 

     setTimeout(function(){ 
     clearInterval(sh); 
     },2000) 
2

La versione 5.14.2 di codemirror lo indirizza completamente con un add on. Vedi this answer per i dettagli.

4

Mi capita di usare CodeMirror all'interno di una scheda di bootstrap. Sospettavo che le schede di bootstrap fossero ciò che impediva la visualizzazione fino al clic. Ho risolto questo problema semplicemente chiamando il metodo refresh() in mostra.

var cmInstance = CodeMirror.fromTextArea(document.getElementById('cm'), { 
    lineNumbers: true, 
    lineWrapping: true, 
    indentUnit: 4, 
    mode: 'css' 
}); 

// to fix code mirror not showing up until clicked 
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function() { 
    this.refresh(); 
}.bind(cmInstance)); 
8

Solo nel caso, e per tutti coloro che non legge la documentazione con sufficiente attenzione (come me), ma si imbatte in questo. C'è uno autorefresh addon solo per quello.

È necessario aggiungere autorefresh.js nel file. Ora puoi usarlo in questo modo.

var editor =CodeMirror.fromTextArea(document.getElementById("id_commentsHint"), { 
    mode: "javascript", 
    autoRefresh:true, 
    lineNumbers: false, 
    lineWrapping: true, 

}); 

funziona come un fascino.

+0

Questo ha funzionato per me. Usare 'setTimeout' con un tempo reale all'interno è imprevedibile e questa è stata l'unica cosa che ha funzionato per me finora. Questa soluzione è molto più robusta. – brandaemon

+0

Questo funziona solo per me quando ho un singolo setValue(). Tuttavia, se voglio impostare il valore più volte, devo ancora mettere a fuoco manualmente l'editor CodeMirror. – phpheini

+0

@phpheini Ho anche lo stesso problema. Hai scoperto un modo per affrontare questo? – prismaticorb

Problemi correlati