CKEditor,AJAX 保存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1956967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CKEditor, AJAX Save
提问by AnApprentice
Can you provide an example on how to setup CKEditor to save via AJAX using the Save button in the CKEditor toolbar?
您能否提供一个示例,说明如何使用 CKEditor 工具栏中的“保存”按钮设置 CKEditor 以通过 AJAX 进行保存?
I'm interested in creating a CKEditor AJAX save page but am not seeing any examples on their site.
我有兴趣创建一个 CKEditor AJAX 保存页面,但在他们的网站上没有看到任何示例。
Thanks!
谢谢!
回答by Korikulum
You can use the beforeCommandExecevent & cancel()method:
您可以使用beforeCommandExec事件和cancel()方法:
<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>
Update:
更新:
This doesn't work in CKEditor versions 4.0, 4.1, 4.2, however it works again since version 4.3.
这在 CKEditor 版本4.0、4.1、4.2 中不起作用,但是从版本4.3 开始它再次起作用。
Since CKEditor version 4.2you can use the saveevent with the cancel()method:
从 CKEditor 4.2版开始,您可以使用带有cancel()方法的save事件:
CKEDITOR.instances[id].on('save', function (event) {
event.cancel();
$(form).submit();
});
回答by Ben
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):
尝试直接从 _source/plugins/save/plugin.js 复制并根据需要进行更改。在 /path/to/ckeditor/plugins (即不在 /path/to/ckeditor/_source/plugins 中)创建您的新插件。例如,在 /path/to/ckeditor/plugins 中创建一个新目录“AjaxSave”,然后在该目录中创建一个文件“plugin.js”。然后在该文件中执行以下操作(改编自源文件夹中的普通“保存”插件):
(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'.
然后在定义工具栏的配置中,将“AjaxSave”更改为“Save”。
EDIT: you must also add config.extraPlugins = "ajaxsave"; to the config.
编辑:您还必须添加 config.extraPlugins = "ajaxsave"; 到配置。
回答by Phil
This is the method I use, no plugins required:
这是我使用的方法,不需要插件:
It's simple and reliable and uses the CKEditors built in save button.
它简单可靠,并使用 CKEditors 内置的保存按钮。
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 ).
向 CKEditor 所在的同一表单添加一个不可见的提交按钮(显示:无),并将其 ID 和名称设置为“提交”,然后当 CKEditor 的标准保存按钮为时,输入的 onclick 和表单 onsubmit 都将被执行点击。您可以内联或使用 jquery.bind() 或任何其他方式连接您的事件处理程序。然后添加一个附加到表单 onsubmit 事件的函数来序列化表单并将其发布到表单“action”属性中设置的 url。只需从事件处理程序返回 'False' 以确保表单不会发布。现在,提交表单的任何代码或按钮(包括 ckeditor 保存按钮)都将运行您的处理程序。不需要 CKeditor 插件或 CKeditor 配置。这是一个简化的示例(假设为 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.
更现实的方法可能使用 JQuery.Bind() 并且脚本将位于外部 JS 文件等中,但最终结果是相同的。它起作用是因为输入隐藏了表单的提交函数,因此对 form.submit() 的任何调用都会调用提交按钮的 onclick() 函数(所有浏览器的标准行为)。因为它是一个“提交”按钮,它会导致表单的“onsubmit”事件触发,如果您直接调用 form.submit() 通常不会发生这种情况。因此,您无需插件或使用 CKEditor API 即可获得可靠的松散耦合的保存事件拦截。您也可以将它用于 ajax 保存以外的其他用途,它适用于您需要执行的任何预保存处理。
回答by Matthew
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:
已经有很多答案,但我认为我的解决方案比迄今为止的所有解决方案都更简单、更简洁。这将简单地使用您在 ckeditor 4 中指定的 javascript 覆盖现有保存按钮的功能:
html:
html:
<textarea id="CKEditor1"></textarea>
javascript:
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>
回答by dhrubo
I have posted the simplest ajax save plugin here Ajax save plugin for CKEDITOR 3.x with jquery 1.4.x
我在这里发布了最简单的 ajax 保存插件 Ajax save plugin for CKEDITOR 3.x with jquery 1.4.x
回答by Ryan
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'
});
回答by Dmitry
I've tried Korikulum's method on CKEditor 4 but it posts the form twice so I've come up with this:
我已经在 CKEditor 4 上尝试过 Korikulum 的方法,但它发布了两次表单,所以我想出了这个:
$(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
MyEditor 是带有 ckeditor 类的文本区域的 id
editorForm is the id of the form that wraps the text area
editorForm 是包裹文本区域的表单的id
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.
CKEditor 在表单中初始化时会覆盖 form.submit() 函数,而 event.cancel() 似乎不会阻止表单被发布。所以我不得不用一个只返回 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.
编辑:我忘记将新编辑的数据复制到 textarea 以便它可以与表单的其余部分一起发送。
回答by Hemant Maurya
<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:
创建一个新页面aiq_save.php,然后:
<?php
ECHO $_GET['xyz'];
ECHO $_POST['file'];//post method
?>
And you've done it.
你已经做到了。
回答by Grim
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.
如果元素周围没有 html 表单,您可能会注意到最初按钮是禁用的,不幸的是,这种行为是硬编码的。要启用它,您必须更改按钮的状态。
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>
回答by Peter Krauss
More one solution variation, using AJAX from jQuery. 1) declare the function CKEDITOR.ajaxSAVE; 2) call it for save updated HTML of the textarea.
更多一种解决方案变体,使用来自 jQuery 的 AJAX。1)声明函数CKEDITOR.ajaxSAVE;2)调用它来保存textarea的更新HTML。
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);

