Topic: [HOWTO] Fix AJAX/DOM problems (moving, or re-creating textareas)
Hello all,
I ran into problems trying to use TinyMCE in an AJAX-ified page where the <textarea/> I was attaching TinyMCE to was being swapped in and out via DOM manipulation/AJAX. Namely, the _second_ time my <textarea/> was loaded and I added a TinyMCE editor to it, clicking in or typing into the TinyMCE editor started throwing "this.getDoc() is null" Javascript exceptions and the changes I made in the editor were not being saved (they weren't copying back to the <textarea/>).
I spent all day in the Javascript debugger trying to figure this out (I didn't know much about Javascript before this morning) and promised myself I'd post the solution if I found it.
Basically, the problem is that when you swap out the <textarea/> element in the DOM, the TinyMCE iFrame is not removed. The old editor instances (mce_editor_0 ... mce_editor_[n - 1]) stay in tinyMCE.instances[] and end up receiving all of the onFocus() and typing events. This causes errors because these old instances are pointing to your old (and now-deleted) <textarea/> elements.
To solve this, you have to make sure that you remove the TinyMCE editor instances before you remove the backing <textarea/> instances. When you next load a <textarea/> you want to attach TinyMCE to, you have to add it explicitly again. If your <textarea/> has an id of "txaEditableContent", you should use the following algorithm/pseudocode:
1. Load the page. Include the following code to init TinyMCE:
tinyMCE.init({
mode : "none",
theme : "simple"
});2. Load a panel/div containing a <textarea/> with an id of "txaEditableContent".
3. Add a TinyMCE editor to that <textarea/>:
tinyMCE.execCommand('mceAddControl', false, 'txaEditableContent');4. User makes and saves their changes in the editor.
5. Unload/swap out the panel/div containing the <textarea/>. Before you remove the <textarea/> make sure you remove the TinyMCE editor:
tinyMCE.execCommand('mceRemoveControl', false, 'txaEditableContent');6. User does something that causes you to load a new panel/div containing a <textarea/> whose id is also "txaEditableContent".
7. Add a TinyMCE editor to that <textarea/>:
tinyMCE.execCommand('mceAddControl', false, 'txaEditableContent');8. Rinse.
9. Repeat as desired.
I hope this helps save someone else from the headache I had today. Happy hacking!
-- Karl M. Davis