web-dev-qa-db-fra.com

Utilisation de jQuery pour récupérer le contenu de CKEditor iframe

J'ai un CMS personnalisé qui utiliseCKEditor* (FCKEditor v3) pour l'édition de contenu. J'utilise également le plug-injQuery Validationpour vérifier l'absence d'erreur dans tous les champs avant la soumission basée sur AJAX. J'utilise la fonctionserialize ()pour transmettre les données au backend PHP.

Le problème est que serialize parvient à récupérer correctement tous les champs, à l'exception du contenu saisi dans CKEditor. Comme tout autre éditeur WYSIWYG, celui-ci recouvre également un iframe sur une zone de texte existante. De plus, serialize ignore l'iframe et ne recherche que le contenu dans la zone de texte, qu'il ne trouve bien sûr pas, ce qui renvoie un corps de contenu vide. 

Mon approche consiste à créer un lien sur l'événement onchange de CKEditor et à mettre à jour simultanément la zone de texte (CKEDITOR.instances.[textboxname].getData()renvoie le contenu) ou un autre champ masqué avec les modifications apportées à l'éditeur. . 

Cependant, CKEditor étant toujours en phase bêta et manquant cruellement de documentation, je ne trouve pas d'appel API approprié qui me permette de le faire. 

Quelqu'un at-il une idée sur la façon de s'y prendre?

24

Une autre solution générique à 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 du formulaire à mettre à jour leurs champs respectifs.

34
Gabriele Petrioli

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

7
Diego A.

J'ai également essayé de résoudre ce problème aujourd'hui. J'ai réalisé que la raison pour laquelle le code ci-dessus ne fonctionnait pas pour moi est que l'instance de CKEditor n'est pas encore prête lorsque la propriété de document est référencée. Vous devez donc appeler l'événement "instanceReady" et utiliser ceux-ci dans le document, car il n'existait pas auparavant.

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);
}
6
Seb Woolford

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

edit: section ajoutée pour mettre à jour la zone de texte après les pâtes, aussi ...

3
Stobor

J'ai eu du succès avec ceci:

console.log(CKEDITOR.instances.editor1.getData());
2
a.m.

CKEDITOR.instances.wc_content1.getData() renverra les données de ckeditor
CKEDITOR.instances.wc_content1.setData() définira les données du ckeditor 

1
Mahesh

Ne vaudrait-il pas mieux faire ceci:

CKEDITOR.instances.editor1.on('contentDom', function() {
          CKEDITOR.instances.editor1.document.on('keyup', function(event) {/*your instructions*/});
        });

ref: http://cksource.com/forums/viewtopic.php?f=11&t=18286

1
netfed

J'ai adopté une approche légèrement différente. Je pensais qu'il serait préférable d'utiliser la fonction de mise à jour de ckeditor et, comme keyup était utilisé, le délai d'attente 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(); 
}
1
mcgrailm

L'événement contentDom a fonctionné pour moi et non l'instanceReady ... J'aimerais vraiment savoir quels sont les événements, 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);
})
1
GoodNews

J'ai essayé toute la nuit pour que ça fonctionne, mais ça ne marche pas encore. Pourriez-vous s'il vous plaît expliquer où vous avez placé ce script? 

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

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

alors 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
Fraser

Je pense que l'utilisateur posait des questions sur la sérialisation, je me débattais pour sérialiser un formulaire à soumettre et cela me causait 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;
    });
 });
0
user731144

J'ai résolu ce problème avec la version actuelle: http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js

Après ligne 55 this.submit (function (event) { - j’ai ajouté ce code:

if (typeof CKEDITOR !== "undefined") {
    for ( instance in CKEDITOR.instances )
        CKEDITOR.instances[instance].updateElement();
}
0
heuri