TinyMCE:Turn tinyMCE into an Ajax editor
From Moxiecode Documentation Wiki
Updated to work with tinyMCE 3.x. (12th March 2008)
NOTE: A quote from spocke on my posts in the forum [1] about the described method:
I think the example should be rewritten now since the 3.x API can to XHR and JSON encoding so no third party library is required to make Ajax save and load. I will look in to this when I get the time.
You can find all about the native tinyMCE XHR methods over here:
http://wiki.moxiecode.com/index.php/TinyMCE:API/tinymce.util.XHR
http://wiki.moxiecode.com/index.php/TinyMCE:API/tinymce.util.XHR/send
You can find all about the native tinyMCE JSON methods over here:
http://wiki.moxiecode.com/index.php/TinyMCE:API/tinymce.util.JSON
So this article is mainly of use for those whom use prototype.js anyway.
I wrote this article because I have spent some time figuring out how to make tinyMCE a fully Ajax-compatible editor and I know it will be useful for others.
At first I found it a pity not to be able to use the Save button from the save plugin to trigger an Ajax http request. But this is the way to customize tinyMCE so you can pass the right values with Ajax to your server, have a neat looking editor with a save button to submit the form and keeping all of your possible callback functions or plug ins working. Oposite to the "Easier way" below, I don't use the save_callback to handle the HTTP request, so I can still use that callback method for something else. also, I noticed that some of my callbacks to clean up the tinyMCE generated html (replace font tags with span tags and so, to get it all in valid xhtml), didn't execute using the save_callback method. Personally I find my method working neater and not that big a hassle at all. The only thing you have to do is change one line in the code of the save plugin and I can use it anyhow anywhere without much trouble. But it's up to you to judge the ease of it for yourselves.
Go to editor_plugin.js -> plugins/save/editor_plugin_src.js.
Find following line:
formObj.submit();
Replace it with :
postForm(ed);
Remember the name of the function, you'll need it to process your http request. Now, you're set to go.
So you add plugins: "save".
tinyMCE.init({
...
plugins : "paste, save",
...
theme_advanced_buttons1_add_before : "save",
...
cleanup_on_startup : true,
cleanup: true,
debug : false
});
You want to have the option cleanup set to true, too.
My postForm function looks like this, I use the prototype library [2] for handling Ajax:
function postForm(ed){
var content = ed.getContent(); //-> get the processed content
var editAreaId = ed.id; //-> get the id of the editor in a multiple editor environment, so you can handle the right editor area after the server response
content = content.replace(/\+/g, "+");
content = content.replace(/\\/g, "\");
content = escape(content);
var url = 'update.php';
var pars = editAreaId + '=' + content;
var myAjax = new Ajax.Request(
url,
{
method: 'post',
postBody: pars,
onComplete: showResponse
}
);
}
I use getContent() to grab the, by all my callback and cleanup functions, processed content of the editor. And to get the id of my textarea I use ed.id.
When the request is completed, showResponse will have to handle the right editor when having multiple editors on a page. So I let update.php return the value together with the id of the textarea in a string which I split. tinyMCE.execInstanceCommand("mceFocus",false,reply[0]) will make sure the right editor gets focus right before insertion in this example. So what ever happens, the text will be inserted in te right editor since tinyMCE.activeEditor.setContent() will always insert values in the editor which has focus. If you just have one text editor on your page you just let setContent() insert the responseText right away, of course. But knowing the id of the element which is holding the editor, you can do what ever you want with it.
function showResponse(originalRequest) {
var reply = originalRequest.responseText.split("||my tinyMCE id||");
tinyMCE.execInstanceCommand("mceFocus",false,reply[0]); //-> focus the right editor
tinyMCE.activeEditor.setContent(reply[1]); //-> insert the reply
}
Since you would like your page to validate as xhtml 1.0. strict, you still have to place action attributes in your form tags:
<form action="">
<fieldset class="center">
<legend style="color: #FFFFFF; ">Text</legend>
<textarea cols="" rows="" name="tekst" id="text" tabindex="1" style="width:350px; height:125px; " ><?= $text ?></textarea>
</fieldset>
</form>
<form action="">
<fieldset class="center">
<legend style="color: #FFFFFF; ">Footer</legend>
<textarea cols="" rows="" name="footer" id="footer" tabindex="2" style="width:350px; height:50px"><?= $footer ?></textarea>
</fieldset>
</form>
You probably would find the Ajax.Updater class from the prototype library interesting too. It allows you to replace the innerHtml from a selected tag. If you, for instance want to replace the text editor with the altered text, this would be the way to go. You can read all about how to use that class on Sergio Pereira's website with the "Developer Notes for prototype.js" [3] or in the prototype API documentation overhere: [4].
I hope you will find this as useful as I do.
Enjoy!
Dietrich Muylaert
An Easier Way
I needed to do something similar and I looked at this page: [[5]] but to my despair, one couldn't do it from the default "Save" plugin. So, I read this post and thought that all this effort wasn't worth it so I found an easier way to achieve the same effect. Here's how I did it:
configure your tinymce for a save callback:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
save_callback: "sendAjaxRequest"
});
Add an onSubmit attribute to your form:
<form onsubmit="return false;"> ... </form>
... hook up your function
function sendAjaxRequest(){
// ajax stuff here
}
And that's it.
NOTE Even though this method is easier ... it has it's own limitations.
17:13, 13 July 2007 (CEST)
Important if you have included selectable plugins like: Styles, Format, etc.,.. you'll have to put return false; at the end of your submit -> onclick="ajax_submit_function();return false;" or you will get disabled <select disabled="disabled" ...> tags on ajax return! Enjoy!
