Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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/

like image 712
Chuck Avatar asked Oct 11 '13 23:10

Chuck


1 Answers

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

like image 193
mwalsher Avatar answered Sep 28 '22 10:09

mwalsher