6

您能否提供一个示例,说明如何使用 CKEditor 工具栏中的“保存”按钮设置 CKEditor 以通过 AJAX 进行保存?

我有兴趣创建一个 CKEditor AJAX 保存页面,但在他们的网站上没有看到任何示例。

谢谢!

4

10 回答 10

8

您可以使用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>

更新:

这在 CKEditor 版本4.04.14.2中不起作用,但它从版本4.3开始再次起作用。

从 CKEditor 4.2版开始,您可以将save事件与cancel()方法一起使用:

CKEDITOR.instances[id].on('save', function (event) {
    event.cancel();
    $(form).submit();
});
于 2012-03-15T23:56:09.870 回答
5

尝试直接从 _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"
         });
     }
   });
})();

然后在定义工具栏的配置中,将“AjaxSave”更改为“保存”。

编辑:您还必须添加 config.extraPlugins = "ajaxsave"; 到配置。

于 2010-01-10T16:14:55.243 回答
4

这是我使用的方法,不需要插件:

它简单可靠,并使用 CKEditors 内置的保存按钮。

将不可见的提交按钮(显示:无)添加到 CKEditor 所在的同一表单,并将其 ID 和名称设置为“提交”,然后当 CKEditor 的标准保存按钮为时,输入的 onclick 和表单 onsubmit 都将执行点击。您可以内联或使用 jquery.bind() 或任何其他方式连接您的事件处理程序。然后添加一个附加到表单 onsubmit 事件的函数以序列化表单并将其 ajax 发布到表单“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>

更现实的方法可能使用 JQuery.Bind() 并且脚本将位于外部 JS 文件等中,但最终结果是相同的。它之所以有效,是因为输入隐藏了表单的提交函数,因此对 form.submit() 的任何调用都会调用提交按钮的 onclick() 函数(所有浏览器的标准行为)。因为它是一个“提交”按钮,所以它会触发表单的“onsubmit”事件,如果您直接调用 form.submit(),通常不会发生这种情况。所以你可以在没有插件或使用 CKEditor API 的情况下获得可靠的松耦合的保存事件拦截。您也可以将它用于 ajax 保存之外,它非常适合您需要做的任何预保存处理。

于 2013-02-09T05:45:04.253 回答
3

我在这里发布了最简单的 ajax 保存插件 Ajax save plugin for CKEDITOR 3.x with jquery 1.4.x

于 2010-06-26T13:48:36.720 回答
3

已经有很多答案了,但我认为我的解决方案比迄今为止的所有解决方案都更容易和更清洁。这将简单地使用您使用 ckeditor 4 指定的 javascript 覆盖现有的保存按钮的功能:

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>
于 2013-11-08T21:27:56.573 回答
1

附加说明:如果您不想创建自己的图标,请更改

{ 
            label : editor.lang.save, 
        command : pluginName, 
        icon: "/img/save.png" 
     });

{ 
            label : editor.lang.save, 
            command : pluginName, 
            className: 'cke_button_save'
         });
于 2012-01-12T05:45:37.227 回答
1

我在 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 是 ckeditor 类的文本区域的 id

editorForm 是包裹文本区域的表单的id

CKEditor 在表单中初始化时会覆盖 form.submit() 函数,并且 event.cancel() 似乎不会阻止发布表单。所以我不得不用一个只返回false的函数来覆盖这个函数。

编辑:我忘记将新编辑的数据复制到文本区域,以便可以与表单的其余部分一起发送。

于 2013-08-01T15:16:29.557 回答
0

更多一种解决方案变体,使用来自 jQuery 的 AJAX。1) 声明函数CKEDITOR.ajaxSAVE;2) 调用它来保存文本区域的更新 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');
 };

然后,随时调用,使用

 var oEditor = parent.main.CKEDITOR.instances['YourTextAreaID'];
 CKEDITOR.ajaxSAVE(oEditor);  
于 2013-02-17T14:22:28.010 回答
0

如果元素周围没有 html-form,您可能会注意到该按钮最初是 disabled,不幸的是,这种行为是硬编码的。要启用它,您必须更改按钮的状态。

这是我的代码:

<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>
于 2016-05-18T10:22:37.480 回答
0
 <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>

创建一个新页面aiq_save.php,然后:

<?php
    ECHO  $_GET['xyz'];

    ECHO $_POST['file'];//post method
?>

而你已经做到了。

于 2016-05-14T07:49:22.013 回答