11 votes

CKEditor 4 et jQuery UI sortable suppriment le contenu après le tri

J'ai rencontré un problème avec CKEditor 4 et la méthode sortable de jQuery UI. Si je trie un conteneur contenant une instance de CKEditor, la valeur est supprimée et l'erreur "Uncaught TypeError : Cannot call method 'getSelection' of undefined". Cela rend également l'éditeur non éditable. J'ai pu contourner ce problème dans CKEditor 3 avec l'une des astuces suivantes trouvées ici : CKEditor se bloque lors de la réorganisation de l'interface utilisateur de jQuery

En regardant l'inspecteur DOM de Chrome, il apparaît que le contenu de l'iframe est supprimé.

Vous trouverez ci-dessous un code de test rudimentaire :

    <html>
    <head>
        <title>test</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/jquery-ui.min.js"></script>
        <script src="ckeditor.js"></script>
        <script type="text/javascript">
        $(function(){

            var tmpStore = {};
            $('#sortable').sortable({
                cursor: 'move',

                // Hack that use to work on V3 but not on V4:
                // https://stackoverflow.com/questions/3379653/ckeditor-freezes-on-jquery-ui-reorder
                start:function (event,ui) {
                    $('textarea').each(function(){
                        var id = $(this).attr('id');
                        tmpStore\[id\] = CKEDITOR.instances\[id\].getData();
                    })
                 },
                stop: function(event, ui) { 
                    $('textarea').each(function(){
                        var id = $(this).attr('id');
                        CKEDITOR.instances\[id\].setData(tmpStore\[id\]);
                    })
                  }
            });
            $('textarea').each(function(){
                var ckId = $(this).attr('id');
                config = {};
                CKEDITOR.replace(ckId, config);
            })
        })

        li { padding: 10px; width: 800px; height: 300px; }

    </head>
    <body>
        <ul id="sortable">
            <li><textarea id="test1" name="test1">test1</textarea></li>
            <li><textarea id="test2" name="test1">test2</textarea></li>
            <li><textarea id="test3" name="test1">test3</textarea></li>
        </ul>
    </body>
    </html>

6voto

Friendly Code Points 785

J'ai été confronté au même problème et je l'ai résolu en me basant sur les réponses données ici. Veuillez consulter les fichiers ci-dessous

QUESTION : https://jsfiddle.net/33qt24L9/1/

  $(function() {
        $( "#sortable" ).sortable({
      placeholder: "ui-state-highlight"
    });

       CKEDITOR.replace( 'editor1' );
       CKEDITOR.replace( 'editor2' );
       CKEDITOR.replace( 'editor3' );
       CKEDITOR.replace( 'editor4' );

  });

PROBLÈME RÉSOLU : https://jsfiddle.net/57djq2bh/2/

  $(function() {
        $( "#sortable" ).sortable({
      placeholder: "ui-state-highlight",

             start: function (event, ui) 
        {
            var id_textarea = ui.item.find(".ckeditor").attr("id");
            CKEDITOR.instances[id_textarea].destroy();
        },
        stop: function (event, ui) 
        {
            var id_textarea = ui.item.find(".ckeditor").attr("id");
            CKEDITOR.replace(id_textarea);
        }           

    });

       CKEDITOR.replace( 'editor1' );
       CKEDITOR.replace( 'editor2' );
       CKEDITOR.replace( 'editor3' );
       CKEDITOR.replace( 'editor4' );

  });

EDIT : Si comme moi vous aviez des configurations séparées par éditeur, voici un code mis à jour qui vous aidera :

start: function (event, ui)
        {
            $('.wysiwyg', ui.item).each(function(){
                var tagId = $(this).attr('id');
                var ckeClone = $(this).next('.cke').clone().addClass('cloned');
                ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
                CKEDITOR.instances[tagId].destroy();
                $(this).hide().after(ckeClone);
            });
        },

        stop: function(event, ui) {
            // for each textarea init ckeditor anew and remove the clone
            $('.wysiwyg', ui.item).each(function(){
                var tagId = $(this).attr('id');
                CKEDITOR.replace(tagId, ckeConfigs[tagId]);
                $(this).next('.cloned').remove();
            });
        }

Merci à : https://github.com/trsteel88/TrsteelCkeditorBundle/issues/53

3voto

oleq Points 7534

Vous devez recréer CKEditor une fois que la structure DOM sous-jacente est modifiée. Sauvegarder les données de l'éditeur avec editor.getData() avant editor.destroy() et restaurer le contenu avec editor.setData( data ) une fois que vous avez créé une nouvelle instance. Il n'y a pas d'autre moyen de résoudre ce problème car CKEditor dépend fortement de la structure du DOM.

2voto

Errorsupport Points 21

Supprimer CKEditor start Sortable

var ckeConfigs = [];
$('.ui-sortable').sortable({
 start:function (event,ui) {
  $('.lineItemCommentBox', ui.item).each(function(){
    var tagId = $(this).attr('id');
        ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
    CKEDITOR.instances[tagId].destroy();
  });
 },
 stop: function(event, ui) {
  $('.lineItemCommentBox', ui.item).each(function(){
   var tagId = $(this).attr('id');
   CKEDITOR.replace(tagId, ckeConfigs[tagId]);
  });
 }
});

1voto

Vindic Points 1

Le code ci-dessous fonctionne pour moi, nous devons détruire l'éditeur au démarrage et le recréer à la fin du déplacement pour obtenir la valeur de la zone de texte qui contient les données :

jQuery(function($) 
{
    var panelList = $("#nameofyourdiv");
    panelList.sortable(
    {
        handle: ".classofyourdivforsorting", 
        start: function (event, ui) 
        {
            var id_textarea = ui.item.find("textarea").attr("id");
            CKEDITOR.instances[id_textarea].destroy();
        } 
        stop: function (event, ui) 
        {
            var id_textarea = ui.item.find("textarea").attr("id");
            CKEDITOR.replace(id_textarea);
        }           
    });
});

J'espère que cela aidera quelqu'un.

0voto

J'ai résolu ce type de problème en instanciant le CKEditor après avoir ouvert le dialogue jquery.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X