【问题标题】:ckeditor inline save/submitckeditor 内联保存/提交
【发布时间】:2012-11-16 05:10:40
【问题描述】:

我不知道如何从 CKEditor 实例中获取已编辑的数据并将其发布到 url。

我在看这个:

http://nightly.ckeditor.com/3995/samples/inlineall.html

我不知道如何保存更改。我可以将新编辑的数据连同正在编辑的元素的 ID 一起发布到 PHP 中吗?

与此类似:

editor.on('configLoaded', function(){
    // do some stuff
});

我希望我能做这样的事情:

editor.on('clickAway', function(e){
    id = e.id();
    // do some ajax stuff
});

但我似乎在任何地方都找不到任何东西。

有人知道怎么做吗?

谢谢。

【问题讨论】:

    标签: javascript ajax ckeditor


    【解决方案1】:

    我确信有很多方法可以解决这个问题,但这是我的解决方案。我正在使用 Smarty 模板引擎,但这种技术也应该适用于普通 HTML。

    首先,这是一个存储在我的名为“dog_fleas.tpl”的模板文件中的 HTML 示例:

    <script type="text/javascript" src="/js/ckeditor/ckeditor.js"></script>
    <script type="text/javascript" src="/js/admin/mycms.js"></script>
    <div>
      <div id="flea-blurb" tpl="/templates/dog_fleas.tpl" contenteditable="true">
        <h1>My Dog Has Fleas</h1>
        <p>This text is editable via the CMS!</p>
      </div>
      <p>This text is not editable</p>
    </div>
    

    处理内联编辑的 javascript (mycms.js) 是:

    $(document).ready(function() {
    
        CKEDITOR.disableAutoInline = true;
    
        $("div[contenteditable='true']" ).each(function( index ) {
    
            var content_id = $(this).attr('id');
            var tpl = $(this).attr('tpl');
    
            CKEDITOR.inline( content_id, {
                on: {
                    blur: function( event ) {
                        var data = event.editor.getData();
    
                        var request = jQuery.ajax({
                            url: "/admin/cms-pages/inline-update",
                            type: "POST",
                            data: {
                                content : data,
                                content_id : content_id,
                                tpl : tpl
                            },
                            dataType: "html"
                        });
    
                    }
                }
            } );
    
        });
    
    });
    

    上面的代码做了几件事:

    1. 它将任何具有 contenteditable = "true" 属性的 div 标签转换为 inline-editable。
    2. 编辑内容后(模糊),可编辑元素 ID、tpl 文件名和编辑后的内容通过 ajax 调用发送到服务器。

    在我的情况下,tpl 属性是识别正在编辑的文件所必需的。元素 id 指定修改了哪个元素。

    虽然我的示例仅包含一个可编辑区域,但此代码支持单个文件中的多个可编辑区域。

    在服务器端,这是我的 PHP 代码。我正在使用一个框架,所以我的 $this->_POST() 函数可能看起来有点不寻常,但希望你能明白:

        // Get the posted parameters
        $new_content = $this->_POST('content');
        $content_id  = $this->_POST('content_id');
        $tpl_filename = $this->_POST('tpl');
    
        // Get the contents of the .tpl file to edit
        $file_contents = file_get_contents(APPPATH . 'views' . $tpl_filename);
    
        // create revision as a backup in case of emergency
        $revised_filename = str_replace('/', '.', $tpl_filename);
        $revised_filename = ltrim ($revised_filename, '.');
        file_put_contents(APPPATH . 'views/templates/revisions/' . $revised_filename . '.' . time(), $file_contents);
    
        // Prepare to match the DIV tag
        // Credit to: http://stackoverflow.com/questions/5355452/using-a-regular-expression-to-match-a-div-block-having-a-specific-id
        $re = '% # Match a DIV element having id="content".
            <div\b             # Start of outer DIV start tag.
            [^>]*?             # Lazily match up to id attrib.
            \bid\s*+=\s*+      # id attribute name and =
            ([\'"]?+)          # $1: Optional quote delimiter.
            \b' . $content_id . '\b        # specific ID to be matched.
            (?(1)\1)           # If open quote, match same closing quote
            [^>]*+>            # remaining outer DIV start tag.
            (                  # $2: DIV contents. (may be called recursively!)
              (?:              # Non-capture group for DIV contents alternatives.
              # DIV contents option 1: All non-DIV, non-comment stuff...
                [^<]++         # One or more non-tag, non-comment characters.
              # DIV contents option 2: Start of a non-DIV tag...
              | <            # Match a "<", but only if it
                (?!          # is not the beginning of either
                  /?div\b    # a DIV start or end tag,
                | !--        # or an HTML comment.
                )            # Ok, that < was not a DIV or comment.
              # DIV contents Option 3: an HTML comment.
              | <!--.*?-->     # A non-SGML compliant HTML comment.
              # DIV contents Option 4: a nested DIV element!
              | <div\b[^>]*+>  # Inner DIV element start tag.
                (?2)           # Recurse group 2 as a nested subroutine.
                </div\s*>      # Inner DIV element end tag.
              )*+              # Zero or more of these contents alternatives.
            )                  # End 2$: DIV contents.
            </div\s*>          # Outer DIV end tag.
            %isx';
    
        if (preg_match($re, $file_contents, $matches))
        {
            $content_to_replace = $matches[0];
    
            $replacement_content = $content_to_replace;
    
            // Replace the inner content of $replacement_content with $new_content
            $replacement_content = preg_replace('/(<div(?:.*?)>)(?:.*)(<\/div>)/msi',"$1" . $new_content . "$2", $replacement_content);
    
            // Now replace the content_to_replace with $replacement content in the HTML
            $new_file_contents = str_replace($content_to_replace, $replacement_content, $file_contents);
    
            // write out the new .tpl file
            file_put_contents(APPPATH . 'views' . $tpl_filename, $new_file_contents);
        }
    

    上面的 PHP 代码基本上是加载 HTML,用正确的 id 定位 div 标签,然后用通过 ajax 调用发送的内容替换该 div 标签的内容。然后将 HTML 重新保存到服务器。我还包含一些代码来存储备份修订,以防万一出现严重错误。

    我意识到正则表达式并不总是最好的解决方案。就我而言,使用 PHP Dom 对象模型很困难,因为我的 HTML 内容不是有效的 HTML。如果您的系统比我的更简单,您可能会考虑使用 Dom 对象模型。

    我希望这会有所帮助!

    【讨论】:

    • 谢谢!我正在寻找如何为此触发 ajax 请求。您的解决方案非常适合我采用。
    【解决方案2】:

    我找到了以下解决方案:How do I save inline editor contents on the server?

    我正在使用模糊事件

    【讨论】:

    • 好笑。链接的问题被标记为此问题的重复
    【解决方案3】:

    使用@clone45 的上述答案并对其进行修改。数据将通过Save 按钮保存,并且只有在进行了一些更改后才会比较旧数据和新数据。

    覆盖了内联编辑器的现有保存按钮,并包含在下面仅提醒@clone45 答案的一部分。

    <script>
    
    CKEDITOR.disableAutoInline = true;
    $("div[contenteditable='true']").each(function(index) {
        var content_id = $(this).attr('id');
        var tpl = $(this).attr('tpl');
        var oldData = null;
        CKEDITOR.inline(content_id, {
            on: {
                instanceReady: function(event) {
                    //get current data and save in variable
                    oldData = event.editor.getData();
                    // overwrite the default save function
                    event.editor.addCommand("save", {
                        modes: {
                            wysiwyg: 1,
                            source: 1
                        },
                        exec: function() {
                            var data = event.editor.getData();
                            //check if any changes has been carried out
                            if (oldData !== data) {
                                oldData = data;
                                $.ajax({
                                        type: 'POST',
                                        url: 'process.php',
                                        data: {
                                            content: data,
                                            content_id: content_id,
                                            tpl: tpl
                                        }
                                    })
                                    .done(function(data) {
                                        alert('saved');
                                    })
                                    .fail(function() {
                                        alert('something went wrong');
                                    });
                            } else
                                alert('looks like nothing has been changed');
                        }
                    });
                }
            }
        });
    });
    
    </script> 
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 2013-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多