
So, just like everybody else, I heart jQuery. I’ve got a lot of code that already uses Prototype/Scriptaculous, which works fine, but I just have more fun writing with jQuery, and I think the syntax is cleaner. Plus, I’m always finding sick new plugins for jQuery, so I think a lot of other people are also in love and its like a group thing. I’ve been periodically converting some of my older Prototype code to work with my new young hip love, but sometimes its just easier to adapt something new than rewrite, which brings me to the integration of a WYSIWYG editor.
Lately I’ve been favoring the idea of “edit in place” over a backend admin page, at least for clients, because they can see their text directly in context, and navigate naturally to what they want to change. I like the way jEditable works, and I started using jWYSIWYG after finding the jEditable custom input plugin that ties the two together. Its good for simple things, but I wanted more power, which brings me to CKEditor.
CKEditor is the new-ish rewrite of FCKEditor. Its faster than its predecessor, cleaner, and more flexible. Sounds like a winner. My problem was just getting it to play nice with jQuery, and also to work as a custom input for jEditable. I couldn’t find anything for this online already, possibly because it turned out to be very easy to do, but I figured I’d take a stab at it myself. Most of the work was already done by Mika Tuupola in the WYSIWYG input for jEditable, and I really didn’t take the time to try and out-pimp anything in his code. Its all pretty straight forward anyway.
There’s probably another way to do this, but being lazy, I didn’t take the time to dig in further into CKEditor just yet. It seems like CKEditor.replace() uses the id of a textarea to find it, so I needed to set a custom id on the textarea that jEditable created for the in-place edit. jQuery doesn’t have a built-in function like Prototype’s Element.identify() I looked around and found a generateId jQuery function by Mark Gibson and decided to just include that because I’ll probably end up reusing it. Also, I found it necessary to destroy the CKEditor instance after submitting the data, otherwise there were issues when I tried to edit the same text a second time. Maybe I could just look for an existing instance of the editor before trying to just replace the textarea, but it was easy to just clean up each instance after using it.
There was one other issue I ran into while setting it all up. My custom CMS merges all the javascript on a page into a single file and minifies it to speed up loading. CKEditor didn’t like being included in the bundle that way; it caused some kind of invalid operand error. I think something was getting screwed up by putting the already minified ckeditor.js file through my merger module’s minifier filter. The problem disappeared when I excluded CKEditor from my merge process and just loaded it separately, so don’t double minify.
Here are the files. You could merge them into a single file but I kept them separate since my system crams everything together in the end anyway. If you keep them in separate files just remember to include the generateId file first as the plugin depends on it.





6 Comments
Bloody brilliant!
I’d been banging my head on this particular low ceiling all day.
Thanks, man!
-Ken
Hi Jeremy,
I’ve been trying to use your code but I’m not sure if I should replace jWYSIWYG, use both, and many other questions. Can you post an example?
Thanks!
No need for the example, your code is fantastic.
Thanks for posting! I really enjoyed the report. I’ve already bookmark
this article.
hey, thanks for your great tutorial. u saved my day.btw i have successfully implemented jeditable and ckeditor. but only one laps still there is the width and height of the editor? is there any way that i can change to the size of the div that i am editing ?
very nice!
One thing I’d like to add is, that I had to remove
onblur:’cancel’,
from the jquery.jeditable.mini.js, because it kept closing the editor when a popup within ckeditor opened like the “Image” popup.