CKEditor Uncaught TypeError: Cannot call method 'unselectable' of null in EmberJS single page app with multiple editors

26,024

Solution 1

I was having a similar problem with AngularJS and jQuery UI Sortable with multiple CKEditors on the page. Basically a nightmare setup. Not sure if this is even entirely related, but I figured I'd share anyway in case anyone else comes across this issue. It seems to be a bug in CKEditor (http://dev.ckeditor.com/ticket/11924 ?) more than anything.

Whenever the DOM is changed by sortable, I have callbacks that destroy/recreate the CKEs (long story).

I was calling CKEDITOR.remove(ckInstance), which resulted in the same error you were getting.

I also tried calling calling ckInstance.destroy() and ckInstance.destroy(true) (to avoid updating the DOM which had already changed) in my callback, but got the error Cannot read property 'hasAttribute' of undefined (and also Cannot read property 'clearCustomData' of null somewhere along the line).

I was able to resolve this issue via the following:

ckInstance.removeAllListeners(); CKEDITOR.remove(ckInstance);

CKEditor seems to do a terrible job of cleaning up after itself and handles DOM changes incredibly poorly (not to mention Angular...)

Hopefully this saves someone else the ridiculous amount of time it took me to figure it out :)

Solution 2

I had the same issue using Meteor and having multiple ckeditor instances as well. This is a common problem with reactive DOM loading in general in which your app has processed your javaScript calls in the order they're received but the DOM may not be fully loaded.

To solve this I just block the code with a setTimeout.

setTimeout(function(){
    $('#content-area').ckeditor();
},100);

Solution 3

I had put the CKEDITOR.replace line inside a function and while body onload called the function.

I have bumped into same kind of issue in laravel. The CKEDITOR.replace javascript was running before the page completely loaded due to which this error occured.

to make sure that page loaded completely I had put the CKEDITOR.replace line inside a function and while body onload called the function

Solution 4

jQuery doc ready function solved the problem for me

$(document).ready(function () {
    CKEDITOR.replace( 'content' ); 
});

Solution 5

look at @losmescaleros answer here: https://stackoverflow.com/a/25252552/13179424

In a nutshell:

There are issues with popovers causing problems if they aren't removed from the DOM using .remove()

$('body').popover({
                    selector: '[rel=popover]',
                    trigger: "click"
                }).on("show.bs.popover", function(e){
                    // hide all other popovers
                    $("[rel=popover]").not(e.target).popover("destroy");
                    $(".popover").remove();                    
                });
Share:
26,024

Related videos on Youtube

Fred
Author by

Fred

Updated on March 25, 2021

Comments

  • Fred
    Fred about 3 years

    I have a single page app created using EmberJS.

    I have 3 textareas on the page.

    I am rendering the ckeditor once the textarea has been inserted into the dom and I am flagging a property on the controller recording that the ckeditor has been rendered so that I'm not rendering it more than once.

    I'm even looking into the dom to verify that there isn't currently an editor there.

    When refreshing the page, I am getting this error at random:

    Uncaught TypeError: Cannot call method 'unselectable' of null
    

    I do not know what's causing it or now to prevent it. When it doesn't throw that error, all 3 ckeditors appear just fine.

    Here is my intiation code for the editor:

    Lrt.PrioritizationEditableTextArea = Ember.TextArea.extend({
        areaVisible: false,
        isRendered: false,
        isInserted: false,
    
       didInsertElement:function(){
           this.set('isInserted', true);
       },
    
       renderEditor:function(){
           var self = this;
           var selfID = self.get('elementId');
    
            if( !this.get('isRendered') && this.get('isInserted') && $('#'+selfID).parent().find('cke').length === 0 ){
    
                var editor = $('#'+selfID).ckeditor({
                   toolbar:[
                       { name: 'document', items:['Source'] },
                       { name: 'clipboard', items:['Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']},
                       { name: 'editing', items:['scayt']},
                       { name: 'basicstyles', items:['Bold', 'Italic', 'Underline', 'TextColor', 'BGColor', '-', 'RemoveFormat']},
                       { name: 'styles', items:['FontSize']},
                       { name: 'paragraph', items:['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-']}
                   ]
                }).editor;
    
                editor.on('change', function(e){
                   if(e.editor.checkDirty()){
                       self.set('value', editor.getData());
                   }
                });
    
                this.set('isRendered', true);
            }
    
       }.observes('areaVisible')
    });
    

    I am also using the "onChange" plugin for ckeditor to fire off an "onChange" event when anything changes in the editor and am responding to it.

    What I have tried:

    • removing the onChange plugin
    • changing ckeditor to the 4.3 beta version
    • removing the toolbar customizations
    • removing the onChange event listener
    • verify that all textareas have content in them when render

    What do I need to do to fix this?

    EDIT

    Here's the stack trace: (I'm tacking on the ver string in my app)

    a (ckeditor.js?ver=2.0.0:291)
    (anonymous function) (ckeditor.js?ver=2.0.0:287)
    i (ckeditor.js?ver=2.0.0:10)
    CKEDITOR.event.CKEDITOR.event.fire (ckeditor.js?ver=2.0.0:12)
    CKEDITOR.editor.CKEDITOR.editor.fire (ckeditor.js?ver=2.0.0:13)
    CKEDITOR.event.CKEDITOR.event.fireOnce (ckeditor.js?ver=2.0.0:12)
    CKEDITOR.editor.CKEDITOR.editor.fireOnce (ckeditor.js?ver=2.0.0:13)
    (anonymous function) (ckeditor.js?ver=2.0.0:223)
    m (ckeditor.js?ver=2.0.0:203)
    CKEDITOR.scriptLoader.load (ckeditor.js?ver=2.0.0:203)
    (anonymous function) (ckeditor.js?ver=2.0.0:222)
    (anonymous function) (ckeditor.js?ver=2.0.0:210)
    (anonymous function) (ckeditor.js?ver=2.0.0:208)
    m (ckeditor.js?ver=2.0.0:203)
    CKEDITOR.scriptLoader.load (ckeditor.js?ver=2.0.0:203)
    CKEDITOR.resourceManager.load (ckeditor.js?ver=2.0.0:207)
    h (ckeditor.js?ver=2.0.0:209)
    (anonymous function) (ckeditor.js?ver=2.0.0:210)
    m (ckeditor.js?ver=2.0.0:220)
    (anonymous function) (ckeditor.js?ver=2.0.0:220)
    (anonymous function) (ckeditor.js?ver=2.0.0:397)
    (anonymous function) (ckeditor.js?ver=2.0.0:208)
    m (ckeditor.js?ver=2.0.0:203)
    q (ckeditor.js?ver=2.0.0:203)
    r (ckeditor.js?ver=2.0.0:203)
    (anonymous function) (ckeditor.js?ver=2.0.0:204)
    

    EDIT #2:

    Here is a fiddle of the specific area of the application where the issue is occuring: http://jsfiddle.net/sSaCd/3/

  • sydneyos
    sydneyos over 9 years
    That worked for me in a similar nightmare scenario for CK Editor (Backbone/Marionette). Thanks!
  • Gherman
    Gherman over 9 years
    using removeAllListeners and remove instead of destroy helped me. Can it be because destroy runs before other functions like replace manage to finish? Was experiencing same errors using Vue.js framework.
  • chakeda
    chakeda about 8 years
    Quick and easy solution. Works with AngularJS.
  • Whelkaholism
    Whelkaholism almost 7 years
    Excellent, thanks - and with Knockout you can use ko.utils.domNodeDisposal.addDisposeCallback to ensure it is called whenever your element is destroyed.
  • Mohammedsalim Shivani
    Mohammedsalim Shivani over 4 years
    It has been almost 5yrs since the answer is posted, but it's still helpful.
  • vhbazan
    vhbazan almost 4 years
    Hi @Valamas, I see your point and I'd like to do something similar to my issue when running karma, but the ckeditor file that my angular project is reading is pointing to a cdn file: TypeError: Cannot read property 'unselectable' of null at e (cdn.ckeditor.com/4.14.0/standard-all/ckeditor.js:349:119) Do you have any idea how can I make it to point karma to my local ckeditor?
  • marlonjd
    marlonjd over 3 years
    You're the time saver. Thank you so much!!