2013-02-27 4 views
6

Wystąpił problem z CKEditor 4 i sortowalną metodą jQuery UI, gdzie jeśli posortuję kontener z instancją CKEditor, usunie on wartość i wygeneruje błąd "Uncaught" TypeError: Nie można wywołać metody 'getSelection' z undefined ". Uniemożliwia też edytorowi edycję. Udało mi się to obejść w CKEditor 3 z jednym z następujących hacków znalezionych tutaj: CKEditor freezes on jQuery UI ReorderCKEditor 4 i jQuery UI sortable usuwa zawartość po sortowaniu

Patrząc na inspektora DOM z Chrome, wygląda na to, że zawartość elementu iframe została usunięta.

Poniżej jest surowy kod testowy:

 

    <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

Czy masz rozwiązanie? –

Odpowiedz

3

Trzeba odtworzyć CKEditor raz bazowego struktury DOM jest modyfikowany. Zapisz dane edytora za pomocą editor.getData() przed editor.destroy() i przywróć zawartość za pomocą editor.setData(data) po utworzeniu nowej instancji. Nie ma innego sposobu, aby to naprawić, ponieważ CKEditor silnie zależy od struktury DOM.

+0

Użycie destroy() i odtworzenie instancji zdało się załatwić sprawę. – DMC

+0

Czy istnieje prosty sposób na zachowanie danych cofania/ponawiania? – Taylan

-1

Po prostu używam funkcji ckeditorOff() i ckeditorOn(), aby zachować dane i ponownie/usuwać instancje cKeditor podczas ruchu.

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

umieścić oświadczenie typeof ckeditorOff aby kod zgodny z przyszłymi wersjami CKEditor w przypadku gdy zdecydują się usunąć te dwie funkcje.

+1

Czy istnieją określone funkcje "ckeditorOff" i "ckeditorOn", które zapewnia CKEditor? – DMC

+0

Nie Po prostu wkleiłem kod, jak jest. Myślę, że ckeditorOff i On są globalnymi poleceniami. Nie widzę ich usuwania w najbliższej przyszłości. – mAsT3RpEE

+1

jaka jest odpowiedź? Podaj te funkcje ... – coorasse

0

I ve rozwiązać tego rodzaju problemu przez utworzenie wystąpienia CKEditor po otwarciu jQuery dialogowe

0

Poniższy kod działa dla mnie, musimy zniszczyć edytor na początku i odtworzyć go, gdy opór jest zakończony uzyskiwanie wartość textarea, które pochodzą z:

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

Mam nadzieję, że pomaga komuś.

0

Miałem podobny problem z CKEDITOR, kod poniżej działał dla mnie. Zniszczyć instancji CKEditor i wyjąć CKEditor i kiedy przeciągając końce zastąpi obecny textarea z CKEditor ponownie

$("#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(); 

Tutaj #sortable jest id z DIV, który jest sortable i ”.dynamic " jest klasą przypisaną do DIV, które kwalifikuje się do sortowania i " .ckeditor " jest klasą dla Textarea.

Mam moje rozwiązanie od Here, mam nadzieję, że to pomoże komuś w przyszłości.

2

Miałem do czynienia z tym samym problemem i naprawiłem na podstawie odpowiedzi tutaj.Proszę zobaczyć skrzypce poniżej

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

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

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

    }); 

ZDECYDOWANE problem: 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: Jeśli tak jak ja miał oddzielne configs na edytorze oto zaktualizowanego kodu pomoże:

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

dzięki: https://github.com/trsteel88/TrsteelCkeditorBundle/issues/53