Reputation: 908
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:
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/
Upvotes: 14
Views: 26848
Reputation: 56
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();
});
Upvotes: 1
Reputation: 53
jQuery doc ready function solved the problem for me
$(document).ready(function () {
CKEDITOR.replace( 'content' );
});
Upvotes: 2
Reputation: 10240
To add to @thatgibbyguy answer, in case it's not clear. If his answer didn't work for you or returned ckeditor not found, it is becasue it doesn't exist as a function if you followed the laravel-ckeditor documentation with composer installation. Which in that case you need to slightly modify his answer this way and it will work
<script src="/vendor/unisharp/laravel-ckeditor/ckeditor.js"></script>
<script>
setTimeout(function(){
CKEDITOR.replace( 'article-ckeditor' ); //Your selector must match the textarea ID
},400);
</script>
Mind you, I am referring to it as a vendor. Look up artisan instructions to include it in your vendor's resources. But I imagine it will work just the same with the CDN installation.
Upvotes: 1
Reputation: 358
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
Upvotes: 2
Reputation: 24729
I just edited the minified file (leaving notes in a text file for developers) and just changed where my error was occurring to check for null from
&&a.ui.space("top").unselectable();
to
&&a.ui.space("top")!=null&&a.ui.space("top").unselectable();
I did this in two places.
Upvotes: 1
Reputation: 4113
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);
Upvotes: 16
Reputation: 2790
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 :)
Upvotes: 27
Reputation: 4685
Try calling ck_editor.destroy
where ck_editor
is your editor instance. For some reason CKEDITOR seems to hang on to old instances. If you destroy them, the error seems to go away.
MyView: Ember.View.extend
# Hang on to the reference for your editor
didInsertElement: ->
@set('ck_editor', CKEDITOR.replace('whatever'))
# Tear down your instanc
willDestroyElement: ->
if @get('ck_editor')
@get('ck_editor').destroy()
Upvotes: 0