2013-02-27 11 views
6

Ho riscontrato un problema con CKEditor 4 e il metodo ordinabile di jQuery UI in cui se ordino un contenitore che ha un'istanza CKEditor, rimuove il valore e genera un errore "Uncaught TypeError: impossibile chiamare il metodo 'getSelection' di undefined ". Inoltre rende l'editor non modificabile. Sono stato in grado di aggirare questo problema in CKEditor 3 con uno dei seguenti hack trovati: CKEditor freezes on jQuery UI ReorderCKEditor 4 e jQuery UI sortable rimuove il contenuto dopo l'ordinamento

Osservando l'ispettore DOM di Chrome, sembra che il contenuto dell'iframe sia stato rimosso.

Di seguito è grezzo codice di prova:

 

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

+0

hai preso la soluzione? –

risposta

3

Bisogna ricreare CKEditor volta sottostante la struttura DOM viene modificata. Salvare i dati dell'editor con editor.getData() prima del editor.destroy() e ripristinare i contenuti con editor.setData(data) dopo aver creato una nuova istanza. Non c'è altro modo per risolvere questo problema poiché CKEditor dipende fortemente dalla struttura DOM.

+0

L'uso di destroy() e la ricreazione delle istanze sembravano fare il trucco. – DMC

+0

Esiste un modo semplice per conservare i dati di annullamento/ripristino? – Taylan

-1

Semplicemente uso le funzioni ckeditorOff() e ckeditorOn() per mantenere i dati e le istanze di ckeditor re/de-instance durante lo spostamento.

$('#sortable').sortable({ 
    cursor: 'move', 
    start:function (event,ui) { 
     if(typeof ckeditorOff=='function')ckeditorOff(); 
    }, 
    stop: function(event, ui) { 
     if(typeof ckeditorOn=='function')ckeditorOn(); 
    } 
}); 

ho messo la dichiarazione typeof ckeditorOff per rendere il codice compatibile con le versioni future di ckeditor nel caso in cui si decide di rimuovere queste due funzioni.

+1

Esistono funzioni specifiche "ckeditorOff" e "ckeditorOn" fornite da CKEditor? – DMC

+0

No Ho semplicemente incollato il codice così com'è. Penso che ckeditorOff e On siano comandi globali. Non li vedo rimuoverli nel prossimo futuro. – mAsT3RpEE

+1

che tipo di risposta è? Fornire queste funzioni ... – coorasse

0

i ve risolto questo tipo di problema da istanziare la CKEditor dopo aver aperto la finestra di jquery

0

Il seguente codice funziona per me, abbiamo a distruggere l'editor su start e ricrearlo quando la resistenza è finito ricevendo il valore della textarea da cui provengono i dati:

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

Spero che aiuti qualcuno.

0

Ho avuto il problema simile con CKEDITOR, il codice qui sotto ha funzionato per me. Distruggere l'istanza ckeditor e rimuovere il ckeditor e quando le estremità trascinamento sostituiscono textarea corrente con ckeditor nuovamente

$("#sortable").sortable({ 
     items: '.dynamic', 
     start: function (event , ui) { 

       var editorId = $(ui.item).find('.ckeditor').attr('id');// get the id of your Ckeditor 
       editorInstance = CKEDITOR.instances[editorId]; // Get the Ckeditor Instance 
       editorInstance.destroy(); // Destroy it 
       CKEDITOR.remove(editorId);// Remove it 

     }, 
     stop: function(event, ui) { 
       var editorId = $(ui.item).find('.ckeditor').attr('id');// Get the Id of your Ckeditor 
       CKEDITOR.replace(editorId);// Replace it 
      } 
     } 

    }); 
    $("#sortable").disableSelection(); 

Qui #sortable rappresenta l'id del DIV che è sortable e ' .dynamic ' è la classe assegnata a DIV che è idonea per ordinare e ' .ckeditor ' è la classe per l'area di testo.

Ho ottenuto la mia soluzione da Here, Spero che questo aiuti per qualcuno in futuro.

2

Ero di fronte allo stesso problema e ho risolto in base alle risposte qui.Si prega di consultare i violini sotto

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

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

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

    }); 

risolto NUMERO: 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: codice Se come me si fosse configurazioni separate per editore Ecco aggiornato che aiuterà:

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

Grazie a: https://github.com/trsteel88/TrsteelCkeditorBundle/issues/53

Problemi correlati