Using Rails, tinyMCE and Ajax

tinyMCE is a fantastic WYSIWG html editor. It can be easily embedded with only a few minutes of configuration. Unfortunately, it’s a little painful to use with Ajax. I’ll walk you through some of the gotchas with their solutions inside.

The first trick comes from Dave Astels. He talks about using tinyMCE.triggerSave(true,true) on ajax requests. The two parameters are skipCleanup and skipCallback. What this function does is take the HTML from the tinyMCE editor and copy it back into the text area. This function needs to be called not only before submitting a form, but also before doing any processing of the form data. For instance, if you want to see if the contents of the form have changed, you should first call triggerSave. There are quite a few references to using tinyMCE.execCommand('mceAddControl',false,'field_id'); to enable tinyMCE for an existing text element. Using it is really simple. You can easily add editors to all text areas of a newly added div using:

 $$('#div_id textarea').each(function(elem) {tinyMCE.execCommand('mceAddControl',false,elem.id);});

Aren’t the prototype extensions to collections a wonderful thing?

One major cause of weirdness with tinyMCE is failure to remove elements before deleting them. For instance, if you used the above code to create some tinyMCE editors in a div and then later wanted to remove that div, you would have serious problems when you tried to submit the form. tinyMCE keeps a hash of instances in tinyMCE.instances. When you call triggerSave, it tries to cleanup each instance. If the HTML that is associated with that instance is gone, you’re going to get an ugly error. Luckily, the solution is really simple. Before you remove a div, you simple do the inverse of our snippet above:

 $$('#div_to_remove_id textarea').each(function(elem) {tinyMCE.execCommand('mceRemoveControl',false,elem.id);});

Those are just a couple of simple tricks to use when working with tinyMCE and Ajax. I highly recommend getting comfortable with FireBug. It will make this type of development a lot easier! Also, if you’re seeing odd results, take a look at the tinyMCE instances. They can be accessed using tinyMCE.instances. To look at the first text editor added, you can use tinyMCE.instances['mce_editor_0']. Good luck! Feel free to email us with questions. We’ve be doing a ton of stuff with tinyMCE and rails and don’t mind helping out. We’ll update this post with answers to common questions!</p>