2014-09-03 5 views
6

muszę korzystać CKEditor inline wewnątrz modalnego bootstrap, ale to nie działa ...CKEditor inline w modalnej bootstrap oknie

Znam ten post: How to use CKEditor in a Bootstrap Modal?

Ale to inny mi beacuse I Korzystam z wbudowanego i potrzebuję po prostu zastosować CKEditor do niektórych pól (mam inne z wykorzystaniem własności contenteditable).

JS KOD:

CKEDITOR.disableAutoInline = true; 
CKEDITOR.inline('myModalLabel'); 
CKEDITOR.inline('bodyModal'); 

$.fn.modal.Constructor.prototype.enforceFocus = function() { 
    modal_this = this 
    $(document).on('focusin.modal', function (e) { 
     if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length 
     // add whatever conditions you need here: 
     && 
     !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select') && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) { 
      modal_this.$element.focus() 
     } 
    }) 
}; 

kod HTML

<button type="button" data-toggle="modal" data-target="#modalAddBrand">Launch modal</button> 

<div class="modal fade" id="modalAddBrand" tabindex="-1" role="dialog" aria-labelledby="modalAddBrandLabel" aria-hidden="true"> 
    <div class="modal-dialog modal-lg"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
       <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> 
       <h4 class="modal-title" id="modalAddBrandLabel">add</h4> 

      </div> 
      <div class="modal-body"> 
       <form> 
        <textarea name="editor1" id="editor1" rows="10" cols="80">This is my textarea to be replaced with CKEditor.</textarea> 
       </form> 
      </div> 
      <div class="modal-footer"> 
       <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
       <button id="AddBrandButton" type="button" class="btn btn-primary">Save</button> 
      </div> 
     </div> 
    </div> 
</div> 

JSFiddle:

JSFiddle Example

Czy ktoś może mi pomóc?

+0

Co nie działa? Mógłbym edytować tytuł Modala i ciało bez problemu. –

+0

Mmmm nie mogę tego zrobić za pomocą chrome i Windows 8.1 – chemitaxis

+1

Hmm, masz rację, w mojej wersji Chrome to nie działa, ale działało dobrze na Firefoksie (22 na WinXP, tak dobrze usłyszałeś, XP). Dostaję ten błąd w konsoli Chrome "Instancja edytora" myModalLabel "jest już dołączona do podanego elementu. ' –

Odpowiedz

1

Ok, mimo wszystko, zrobiłem to mieszanka dwóch odpowiedzi ... i to działa teraz ... Co o tym sądzisz?

$(document).ready(function(e) { 
    CKEDITOR.disableAutoInline = true; 
    CKEDITOR.inline('myModalLabel'); 
    CKEDITOR.inline('bodyModal'); 


    $('#myModal').on('shown.bs.modal', function() { 
     ckCreate('myModalLabel'); 
     ckCreate('bodyModal'); 
    }); 
}); 

function ckCreate(name) { 
    if (CKEDITOR.instances[name]) { 

     var instance = CKEDITOR.instances[name]; 
     if (instance.element.$) { 
      instance.destroy(true); 
     } 

     $('#' + name).attr('contenteditable', true); 
     CKEDITOR.inline(name); 

    } 

} 
4

Problem polega na tym, że podczas procesu init wystąpienie CKEditor, że docelowy czas jest ukryty, więc jeśli instancję edytora po docelowa jest pokazany będzie wok:

Więc po prostu umieścić:

CKEDITOR.disableAutoInline = true; 

$('#myModal').on('shown.bs.modal', function() { 
    CKEDITOR.inline('myModalLabel'); 
    CKEDITOR.inline('bodyModal'); 
}); 

Ale po zamknięciu i ponownym otwarciu modal może pojawić się błąd:

Uncaught The editor instance "myModalLabel" is already attached to the provided element

Aktualizacja:

Do tego możemy mieć funkcję:

function ckCreate(name) 
{ 
    if(CKEDITOR.instances[name] === undefined) 
    { 
     CKEDITOR.inline(name); 
    } 
} 

tworzyć tylko instancję jeśli nie istnieje;

Wreszcie kod byłoby:

CKEDITOR.disableAutoInline = true; 

$('#myModal').on('shown.bs.modal', function() { 
    ckCreate('myModalLabel'); 
    ckCreate('bodyModal'); 
}); 

Finał Fiddle: http://jsfiddle.net/0vLs3fku/4/

Aktualizacja: w potrzebie zniszczenia przypadkach

function ckCreate(name) 
{ 
    if (CKEDITOR.instances[name]) 
    { 
     CKEDITOR.instances[name].destroy(); 
    } 

    CKEDITOR.inline(name); 
} 
+0

Dobra robota, dziękuję i pozdrawiam – chemitaxis

+0

Dziękuję też, serdecznie zapraszamy w każdej chwili;)) –

3

Wydaje się być to znany bug wpływając WebKit/migać przeglądarek. Powodem jest to, że gdy element jest ukryty, usunięto atrybut contenteditable iw tym przypadku instancja CKEDITOR musi zostać zniszczona i odtworzona, atrybut contenteditable musi być ustawiony na true.

Z tego powodu można ustawić atrybut ponownie, gdy okno dialogowe jest wyświetlane przy użyciu zdarzenia shown.bs.modal.

Musisz pobrać wszystkie elementy ex contenteditable dla dzieci z otwartego okna dialogowego.

Kod:

$('#myModal').on('shown.bs.modal', function (e) { 
    $(this).find("*[contenteditable='false']").each(function() { 
     var name; 
     for (name in CKEDITOR.instances) { 
      var instance = CKEDITOR.instances[name]; 
      if (this && this == instance.element.$) { 
       instance.destroy(true); 
      } 
     } 
     $(this).attr('contenteditable', true); 
     CKEDITOR.inline(this); 
    }) 
}); 

Demo: http://jsfiddle.net/IrvinDominin/q5zxn3yf/

+0

dlaczego instancja musi zostać zniszczona? W moim przykładzie działa bez niego, wydajność jest również ważna, myślę, że –

+0

@GeorgeGarchagudashvili to pozwoli kodowi pracować z nowo utworzonym/dodanym elementem również i ze złamanymi instancjami –

+1

Jeśli to działa, to nie zostanie złamane, tak. –