2009-05-29 5 views
24

J'ai un CMS personnalisé qui utilise CKEditor * (FCKEditor v3) pour éditer le contenu. J'utilise également le plugin jQuery Validation pour vérifier tous les champs d'erreur avant la soumission basée sur AJAX. J'utilise la fonction serialize() pour transmettre les données au backend PHP.Utilisation de jQuery pour récupérer le contenu de l'iframe de CKEditor

Le problème est que serialize parvient à saisir tous les champs correctement, à l'exception du contenu réel tapé dans CKEditor. Comme tous les autres éditeurs WYSIWYG, celui-ci recouvre également un iframe sur une zone de texte existante. Et sérialiser ignore l'iframe et ne regarde que dans la zone de texte pour le contenu, ce qui, bien sûr, ne trouve pas, renvoyant ainsi un corps de contenu vide.

Mon approche de c'est de créer un crochet sur le onchange événement de CKEditor et mettre à jour en même temps que la zone de texte (CKEDITOR.instances.[textboxname].getData() renvoie le contenu) ou d'un autre champ caché avec les modifications apportées dans l'éditeur.

Cependant, étant donné que CKEditor est encore en phase bêta et qu'il manque cruellement de documentation, je ne trouve pas d'appel d'API approprié qui me permettra de le faire.

Quelqu'un a-t-il une idée sur la façon de procéder?

+1

J'ai compris jusqu'à saisir le contenu de l'iframe: $ ('#cke_contents_body iframe') .contents(). Find ('body') .html() ... l'élément directement adressable le plus proche étant un td avec l'identifiant 'cke_contents_body'. CKEditor enveloppe l'iframe avec ce td. –

+0

Encore à faire .. un moyen de mettre à jour automatiquement la zone de texte avec les données en accrochant sur un événement de changement de CKEditor. Des idées? N'importe qui? –

+1

Nouvelle version de CKEditor a résolu ce problème – Ivan

Répondre

3

Cela devrait le faire ...

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

modifier: section ajoutée à jour après pâtes textbox aussi ...

+0

Merci pour votre réponse ... mais il ne cesse de me dire: "CKEDITOR.instances.editor1.document est undefined" !! –

+0

BTW, pouvez-vous s'il vous plaît expliquer pourquoi vous utilisez un setTimeout ici et ne pas simplement copier le contenu directement sur la frappe? –

+2

remplacez editor1 par votre textboxname.Le setTimeout doit s'assurer que nous obtenons le contenu _après_ que la touche enfoncée est ajoutée, plutôt qu'avant. – Stobor

6

J'ai aussi essayé de résoudre ce problème aujourd'hui. J'ai réalisé que la raison pour laquelle le code ci-dessus ne fonctionne pas pour moi est parce que l'instance de CKEditor n'est pas encore prête quand la propriété de document est référencée. Vous devez donc appeler l'événement "instanceReady" et dans ce cas, les événements du document peuvent être utilisés, car avant cela, il n'existe tout simplement pas.

Cet exemple pourrait fonctionner pour vous:

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

Merci à vous tous :) Le code combiné a fait l'affaire ... –

+0

$ ("# editor1"). Val (CKEDITOR.instances.editor1.getData()); Merci –

0

J'ai essayé toute la nuit pour que cela fonctionne, mais il ne fonctionne pas encore. Pourriez-vous expliquer où vous avez placé ce script?

Je génère ma page à partir d'un xquery, donc je ne peux pas mettre ce script dans la page car il contient "{" qui casse le traitement de xquery. Mettre le script dans cdata casse le script. J'ai donc mis l'écouteur instanceReady dans le même script que celui qui crée l'éditeur et j'ai appelé un script externe pour ajouter le reste.par exemple:

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

puis updateInstance contient:

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

Pour une question de suivi comme celle-ci, il serait préférable de la poser comme une nouvelle question (bouton «Poser une question» en haut à droite de la page), et de ne pas la poster ici dans un ancien fil. Plus de gens le verraient et essayer de résoudre votre problème ... – sth

+0

Ok merci, nouveau sur ce site et ne savait pas comment cela fonctionne. Je vais supprimer d'ici et republier comme une nouvelle question. – Fraser

+0

Ok, j'ai résolu mon problème. Je mélangeais du code xquery et javascript et n'échappions pas correctement au {. Fonctionne bien maintenant. Merci pour la solution !! – Fraser

7

Je viens de publier un plugin CKEditor pour jQuery qui prendra soin de tout cela en arrière-plan sans code supplémentaire: http://www.fyneworks.com/jquery/CKEditor/

+0

Des trucs sympas. Merci. C'est sûr que c'est facile. –

+0

Est-ce que ce plugin fonctionne encore pour le nouveau CKEDITOR? – AnApprentice

1

J'ai pris une approche légèrement différente J'ai pensé qu'il serait préférable d'utiliser la fonction de mise à jour de ckeditor et puisque le clavier était utilisé, le timeout n'était pas nécessaire

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

Une autre des solutions génériques à cela serait d'exécuter ce qui suit chaque fois que vous essayez de soumettre le formulaire

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

Cela forcera toutes les instances de ckeditor sous la forme de mettre à jour leurs champs respectifs

+0

Est-ce un code javascript? – Bajrang

+1

@ J.J. Oui. c'est un code javascript qui devrait être exécuté sur l'événement 'submit' du formulaire (* ou à tout moment avant *). –

+0

Gaby aka G. Petrioli - Merci. – Bajrang

2

j'avais succès avec ceci:

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

L'événement contentDom a fonctionné pour moi et non le instanceReady ... Je veux vraiment savoir ce que les événements ae, mais je suppose qu'ils sont propriétaires ...

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

Votre réponse m'a sauvé après près de 4 heures de débogage/réécriture de tout. Ce que j'avais écrit fonctionnait très bien en utilisant "instanceReady", mais cela ne fonctionnait pas du tout sur AJAXed dans le contenu. Je voulais juste dire merci. – narx

1

CKEDITOR.instances.wc_content1.getData() renverra les données ckeditor
CKEDITOR.instances.wc_content1.setData() fixeront les données ckeditor

0

Je pense que l'utilisation Je m'interrogeais sur la sérialisation, je luttais pour sérialiser un formulaire à soumettre et cela me donnait beaucoup de problèmes.

C'est ce qui a fonctionné pour moi:

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