2009-05-29 15 views
24

Ho un CMS personalizzato che utilizza CKEditor * (FCKEditor v3) per la modifica del contenuto. Sto anche usando il plugin jQuery Validation per controllare tutti i campi per errori prima dell'invio basato su AJAX. Sto usando la funzione serialize() per passare i dati al backend PHP.Utilizzo di jQuery per prelevare il contenuto dall'iframe di CKEditor

Il problema è che serialize è in grado di acquisire tutti i campi correttamente, ad eccezione del contenuto effettivo digitato in CKEditor. Come ogni altro editor WYSIWYG, anche questo sovrascrive un iframe su una casella di testo esistente. E serializza ignora l'iframe e guarda solo nella casella di testo per il contenuto, che, naturalmente, non trova, restituendo così un corpo di contenuto vuoto.

Il mio approccio a questo è quello di creare un gancio sul caso onchange di CKEditor e contemporaneamente aggiornare la casella di testo (CKEDITOR.instances.[textboxname].getData() restituisce il contenuto) o qualche altro campo nascosto con le eventuali modifiche apportate nell'editor.

Tuttavia, poiché CKEditor è ancora in fase beta e manca di documentazione, non riesco a trovare una chiamata API adatta che mi consenta di farlo.

Qualcuno ha qualche idea su come andare su questo?

+1

Ho capito fino ad afferrare il contenuto dall'iframe: $ ('#cke_contents_body iframe') .contents(). Find ('body') .html() ... l'elemento direttamente più vicino indirizzabile è un td con id, 'cke_contents_body'. CKEditor avvolge l'iframe con questo td. –

+0

Ancora per andare .. un modo per aggiornare automaticamente la casella di testo con i dati agganciando un evento di modifica di CKEditor. Qualche idea? Chiunque? –

+1

La nuova versione di CKEditor ha risolto questo problema – Ivan

risposta

3

Questo dovrebbe farlo ...

CKEDITOR.instances["editor1"].document.on('keydown', function(event) 
{ 
    CKEDITOR.tools.setTimeout(function() 
    { 
     $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0); 
}); 

CKEDITOR.instances["editor1"].document.on('paste', function(event) 
{ 
    CKEDITOR.tools.setTimeout(function() 
    { 
     $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0); 
}); 

edit: Aggiunta la sezione alla aggiornare testo dopo paste, troppo ...

+0

Grazie per la risposta ... ma continua a dirmi: "CKEDITOR.instances.editor1.document è indefinito" !! –

+0

BTW, puoi spiegare perché stai usando un setTimeout qui e non solo copiando il contenuto direttamente dopo la pressione di un tasto? –

+2

sostituisci l'editor1 con il tuo textboxname.Il setTimeout serve ad assicurarci di ottenere il contenuto _after_ il tasto premuto viene aggiunto, piuttosto che prima. – Stobor

6

ho anche cercato di risolvere questo problema oggi. Mi sono reso conto che il motivo per cui il codice sopra non funziona per me è perché l'istanza di CKEditor non è ancora pronta quando viene fatta riferimento alla proprietà del documento. Quindi devi chiamare l'evento "instanceReady" e all'interno del quale è possibile utilizzare gli eventi del documento, perché prima non esisteva.

Questo esempio potrebbe funzionare per voi:

CKEDITOR.instances["editor1"].on("instanceReady", function() 
{ 
//set keyup event 
this.document.on("keyup", CK_jQ); 

//and paste event 
this.document.on("paste", CK_jQ); 
}); 

function CK_jQ() 
{ 

    CKEDITOR.tools.setTimeout(function() 
    { 
     $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0); 
} 
+0

Grazie a tutti voi :) Il codice combinato ha fatto il trucco ... –

+0

$ ("# editor1"). Val (CKEDITOR.instances.editor1.getData()); Grazie di lavoro –

0

ho cercato tutta la notte per arrivare a questo lavoro, ma non è ancora lavorando. Potresti spiegare dove hai inserito questo script?

Sto generando la mia pagina da un xquery, quindi non posso inserire questo script nella pagina perché contiene "{" che interrompe l'elaborazione xquery. Mettere lo script in cdata interrompe lo script. Così ho inserito il listener instanceReady nello stesso script che sta creando l'editor e ho chiamato uno script esterno per aggiungere il resto.ad esempio:

<script type="text/javascript"> 
    var editor = CKEDITOR.replace('editor1'); 
    editor.on("instanceReady", updateInstance()) 
</script> 

poi updateInstance contiene:

function updateInstance() 
{ 
CKEDITOR.instances["editor1"].document.on('keydown', function(event) 
{ 
    CKEDITOR.tools.setTimeout(function() 
    { 
     $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0); 
}); 

CKEDITOR.instances["editor1"].document.on('paste', function(event) 
{ 
    CKEDITOR.tools.setTimeout(function() 
    { 
     $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0); 
}); 

} 
+0

Per una domanda di follow-up come questa, sarebbe meglio chiederla come una nuova domanda (pulsante "Chiedi domanda" in alto a destra della pagina), non postarla qui in una discussione precedente. Altre persone lo vedono e cercano di risolvere il tuo problema ... – sth

+0

Ok grazie, nuovo a questo sito e non ero sicuro di come funziona. Cancellerò da qui e ripeterò come una nuova domanda. – Fraser

+0

Ok ho risolto il mio problema. Stavo mescolando il codice xquery e javascript e non ho scappato correttamente il {. Funziona bene ora. Grazie per la soluzione !! – Fraser

7

Ho appena rilasciato un plugin per jQuery CKEditor, che si prenderà cura di tutto questo in background, senza alcun codice aggiuntivo: http://www.fyneworks.com/jquery/CKEditor/

+0

Cose interessanti. Grazie. Questo sicuramente lo rende facile. –

+0

Questo plug-in funziona ancora per il nuovo CKEDITOR? – AnApprentice

1

Ho seguito un approccio leggermente diverso. Ho pensato che sarebbe stato meglio utilizzare la funzione di aggiornamento del ckeditor e poiché la chiave era in uso non era necessario il timeout

CKEDITOR.instances["editor1"].on("instanceReady", function() 
{ 
//set keyup event 
this.document.on("keyup", CK_jQ); 

//and paste event 
this.document.on("paste", CK_jQ); 
} 

function CK_jQ() 
{ 
    CKEDITOR.instances.editor1.updateElement(); 
} 
34

Un'altra soluzioni generiche a questo sarebbe per eseguire il seguente ogni volta che si tenta di inviare il modulo

for (instance in CKEDITOR.instances) 
      CKEDITOR.instances[instance].updateElement(); 

Questo costringerà tutte le istanze CKEditor in forma di aggiornare i loro rispettivi campi

+0

È un codice javascript? – Bajrang

+1

@ J.J. sì. è un codice javascript che dovrebbe essere eseguito sull'evento 'submit' del modulo (* o in qualsiasi momento prima di esso *). –

+0

Gaby aka G. Petrioli - Grazie. – Bajrang

2

ho avuto successo con questo:

console.log(CKEDITOR.instances.editor1.getData()); 
1

L'evento contentDom funzionato per me e non l'instanceReady ... mi piacerebbe davvero sapere cosa gli eventi AE, ma suppongo che sono proprietari ...

var editor = CKEDITOR.replace('editor'); 

CKEDITOR.instances.editor.on("instanceReady", function(){ 
    this.on('contentDom', function() { 
     this.document.on('keydown', function(event) { 
      CKEDITOR.tools.setTimeout(function(){ 
       $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
      }, 1); 
     }); 
    }); 
    this.on('contentDom', function() { 
     this.document.on('paste', function(event) { 
      CKEDITOR.tools.setTimeout(function(){ 
       $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
      }, 1); 
     }); 
    }); 
    edits_clix(); 
    var td = setTimeout("ebuttons()", 1); 
}) 
+0

La tua risposta mi ha salvato dopo quasi 4 ore di debug/riscrittura di tutto. Quello che avevo scritto funzionava in gran parte usando "instanceReady", ma non funzionava affatto su AJAXed nei contenuti. Volevo solo dire grazie. – narx

1

CKEDITOR.instances.wc_content1.getData() restituirà i dati CKEditor
CKEDITOR.instances.wc_content1.setData() imposterà i dati CKEditor

0

credo l'uso Mi stavo chiedendo di serializzare, stavo lottando per serializzare un modulo da inviare e mi stava dando un sacco di problemi.

Questo è ciò che ha funzionato per me:

$(document).ready(function() { 
$('#form').submit(function(){ 
if (CKEDITOR.instances.editor1.getData() == ''){ 
    alert('There is no data available');//an alert just to check if its working 
}else{ 
    var editor_data = CKEDITOR.instances.editor1.getData(); 
    $("#editor1").val(editor_data); //at this point i give the value to the textarea 
    $.ajax({ 
        //do your ajax here 

        }); 

     } 
return false; 
    }); 
}); 
Problemi correlati