Reputation: 110960
Can you provide an example on how to setup CKEditor to save via AJAX using the Save button in the CKEditor toolbar?
I'm interested in creating a CKEditor AJAX save page but am not seeing any examples on their site.
Thanks!
Upvotes: 6
Views: 29408
Reputation: 131
This is the method I use, no plugins required:
It's simple and reliable and uses the CKEditors built in save button.
Add a non-visible submit button (display:none) to the same form where the CKEditor is and set it's ID and Name to "submit" then both the input's onclick and the forms onsubmit will both be executed when the CKEditor's standard save button is clicked. you can hook up your event handlers inline or with jquery.bind() or any other way. Then add a function attached to the forms onsubmit event to serialize the form and ajax post it to the url set in the form 'action' attribute. Just return 'False' from the event handler to ensure the form does not post. Now any code or button (including the ckeditor save button) that submits the form will run your handler instead. No CKeditor plugins or CKeditor configuration required. Here's a simplified example (assumes JQuery ).
<form id="myform" name="myform" action="" method="post" onsubmit="alert('form.onsubmit()');return false;">
<input type="submit" id="submit" name="submit" style="display:none" onclick="SaveText(this);"/>
<textarea id="ckeditor1"></textarea>
</form>
<script>
function SaveText (eventargs){
var form = $(eventargs).closest("form");
var data = form.serialize();
var url = form.attr('action');
$.post(url, data);
return false;
}
</script>
A more realistic approach might use JQuery.Bind() and the script would be in an external JS file etc. but the end result is the same. It works because the input hides the form's submit function so any call to form.submit() calls the submit button's onclick() function instead (std behavior for all browsers). Because it's a 'submit' button it causes the form's 'onsubmit' event to fire which would not normally happen if you called form.submit() directly. so you get reliable loosely coupled interception of the save event without plugins or using the CKEditor API. you can use it for more than ajax save too, its nice for any pre-save processing you need to do.
Upvotes: 4
Reputation: 1986
If you have no html-form around the element you may notice that initially the button is disabled, this behave is unfortunately hardcoded. To enable it you must change the state of the button.
This is my code:
<script>
function editor(domElement, callback){
var editor = CKEDITOR.replace(domElement);
// save-command currently unavailable because we have no form.
editor.on('instanceReady',function(){
// find the save-command
var command = editor.getCommand('save');
// set the initail state to enabled/unpressed
command.setState(CKEDITOR.TRISTATE_OFF);
// overwrite the exec-command
command.exec = function (){
var newHtml = editor.getData();
callback(newHtml);
editor.destroy();
}
});
}
</script>
Upvotes: 0
Reputation: 174
<textarea cols="80" id="editor1" name="editor1" rows="10"></textarea>
<button id="save" onclick="save()"></button>
<script type="text/javascript">
function save() {
var question = CKEDITOR.instances.editor1.getData();
alert(question);
$.ajax({
type: 'POST',
data: {file: question},
url: "aiq_save.php?xyz="+question+"",
success: function (html) {
alert('may be saved');
$("#show").html(html);
}
});
return false;
</script>
<div id="show"></div>
Create a new page aiq_save.php
, then:
<?php
ECHO $_GET['xyz'];
ECHO $_POST['file'];//post method
?>
And you've done it.
Upvotes: 0
Reputation: 2599
You can use the beforeCommandExec event & cancel() method:
<script type="text/javascript">
$(document).ready(function () {
$('.ckeditoriz').ckeditor(/* config */);
$('.ckeditoriz').each(function () {
var id = $(this).attr('id'),
form = this.form;
CKEDITOR.instances[id].on('beforeCommandExec', function (event) {
if (event.data.name === 'save') {
event.cancel();
$(form).submit();
}
});
});
$('.ajaxForm').submit(function (event) {
event.preventDefault();
var $this = $(this);
$.ajax({
type: $this.attr('method'),
url: $this.attr('action'),
data: $this.serialize()
});
});
});
</script>
<form action="url" method="post" class="ajaxForm">
<!-- Your textarea must have an ID! -->
<textarea id="textarea1" name="textarea1" class="ckeditoriz"></textarea>
</form>
This doesn't work in CKEditor versions 4.0, 4.1, 4.2, however it works again since version 4.3.
Since CKEditor version 4.2 you can use the save event with the cancel() method:
CKEDITOR.instances[id].on('save', function (event) {
event.cancel();
$(form).submit();
});
Upvotes: 8
Reputation: 6609
Lots of answers already but I think my solution is way easier and cleaner than everything here so far. This will simply override the existing save button's functionality with javascript that you specify with ckeditor 4:
html:
<textarea id="CKEditor1"></textarea>
javascript:
<script>
// Need to wait for the ckeditor instance to finish initialization
// because CKEDITOR.instances.editor.commands is an empty object
// if you try to use it immediately after CKEDITOR.replace('editor');
CKEDITOR.on('instanceReady', function (ev) {
// Create a new command with the desired exec function
var overridecmd = new CKEDITOR.command(editor, {
exec: function(editor){
// Replace this with your desired save button code
alert(editor.document.getBody().getHtml());
}
});
// Replace the old save's exec function with the new one
ev.editor.commands.save.exec = overridecmd.exec;
});
CKEDITOR.replace('CKEditor1');
</script>
Upvotes: 3
Reputation: 7266
I've tried Korikulum's method on CKEditor 4 but it posts the form twice so I've come up with this:
$(function () {
setTimeout(function () {
CKEDITOR.instances.MyEditor.on('beforeCommandExec', function (event) {
if (event.data.name === 'save') {
event.cancel();//this does not seem to prevent the form post
$(MyEditor).val(CKEDITOR.instances.MyEditor.getData());//copy data from the editor to the textarea
$.ajax({
type: $(editorForm).attr('method'),
url: $(editorForm).attr('action'),
data: $(editorForm).serialize(),
success: function (data) {
alert(data.message);
}
});
}
});
}, 100);//CKEditor is heavy and needs time to initialize
editorForm.submit = function (e) {//this is needed to prevent the 2nd post
return false;
};
});
MyEditor is the id of the text area with ckeditor class
editorForm is the id of the form that wraps the text area
CKEditor overrides form.submit() function when it's initialized within a form and event.cancel() does not seems to prevent the form being posted. So I had to override the function with one that just returns false.
EDIT: I forgot to copy the newly edited data to the textarea so it could be sent along with the rest of the form.
Upvotes: 1
Reputation: 13930
More one solution variation, using AJAX from jQuery. 1) declare the function CKEDITOR.ajaxSAVE; 2) call it for save updated HTML of the textarea.
CKEDITOR.ajaxSAVE = function ( editor ) {
editor.updateElement();
var htm = editor.getData();
var otherParameter = '...';
if (htm) $.ajax({
type: "POST",
url: "saveHtmFromCKEditor.php",
data: { content: htm, other: otherParameter }
}).done(function( msg ) { // string or JSON object
if (!parseInt(msg)>0) alert( "ERROR WHEN SAVING: " + msg );
});
else
alert('EMPTY HTM. NOT SAVED');
};
Then, for call, at any time, use
var oEditor = parent.main.CKEDITOR.instances['YourTextAreaID'];
CKEDITOR.ajaxSAVE(oEditor);
Upvotes: 0
Reputation: 11
Additional Note: If you don't want to create your own Icon, change
{
label : editor.lang.save,
command : pluginName,
icon: "/img/save.png"
});
to
{
label : editor.lang.save,
command : pluginName,
className: 'cke_button_save'
});
Upvotes: 1
Reputation: 179
I have posted the simplest ajax save plugin here Ajax save plugin for CKEDITOR 3.x with jquery 1.4.x
Upvotes: 3
Reputation: 2077
Try copying straight from _source/plugins/save/plugin.js and changing as needed. Create your new plugin in /path/to/ckeditor/plugins (i.e. Not in /path/to/ckeditor/_source/plugins). For example, in /path/to/ckeditor/plugins create a new directory "AjaxSave", then in that directory create a file "plugin.js". Then in that file do something like this (adapted from the normal "save" plugin in the source folder):
(function()
{
var saveCmd =
{
modes : { wysiwyg:1, source:1 },
exec : function( editor )
{
var $form = editor.element.$.form;
if ( $form )
{
try
{
editor.updateElement();
//Here is where you put your ajax submit function. For example... if you are using
// jQuery and the ajaxform plugin, do something like this:
$($form).ajaxSubmit({
success: function(response){
//do something with the response
}
});
} catch ( e ) {
//alert(e);
}
}
}
}
var pluginName = 'ajaxsave';
CKEDITOR.plugins.add( pluginName,
{
init : function( editor )
{
var command = editor.addCommand( pluginName, saveCmd );
command.modes = { wysiwyg : !!( editor.element.$.form ) };
editor.ui.addButton( 'AjaxSave',
{
label : editor.lang.save,
command : pluginName,
icon: "/img/save.png"
});
}
});
})();
Then in the config, where you define your toolbar, change 'AjaxSave' for 'Save'.
EDIT: you must also add config.extraPlugins = "ajaxsave"; to the config.
Upvotes: 5