2012-11-28 30 views
13

Tôi không thể tìm ra cách lấy dữ liệu đã chỉnh sửa từ một cá thể CKEditor và đăng nó lên một url.ckeditor inline save/submit

Tôi đang nhìn vào một cái gì đó này:

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

và tôi không thể làm việc ra làm thế nào những thay đổi có thể được cứu. Tôi có thể đăng dữ liệu mới được chỉnh sửa để được đăng lên một PHP cùng với ID của phần tử đang được chỉnh sửa không?

Tương tự như thế này:

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

Tôi đã hy vọng tôi có thể làm một cái gì đó như thế này:

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

Nhưng tôi dường như không thể tìm thấy bất cứ điều gì, bất cứ nơi nào.

Có ai đã tìm ra cách thực hiện việc này không?

Cảm ơn bạn.

Trả lời

27

Tôi chắc rằng có rất nhiều cách để kéo giảm giá này, nhưng đây là giải pháp của tôi. Tôi đang sử dụng Smarty Template Engine, nhưng kỹ thuật này cũng sẽ hoạt động với vani HTML.

Trước hết, đây là một ví dụ về một số HTML được lưu trữ trong tập tin mẫu của tôi có tên là "dog_fleas.tpl":

<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> 

Các javascript (mycms.js) để xử lý các chỉnh sửa nội tuyến là:

$(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" 
        }); 

       } 
      } 
     }); 

    }); 

}); 

Đoạn mã trên thực hiện một vài điều:

  1. Nó chuyển đổi bất kỳ thẻ div với contenteditable thuộc tính = "true" để inline-edit có thể.
  2. Sau khi nội dung được chỉnh sửa (làm mờ), id phần tử có thể chỉnh sửa, tên tệp tpl và nội dung đã chỉnh sửa được gửi đến máy chủ thông qua cuộc gọi ajax.

Thuộc tính tpl là cần thiết trong trường hợp của tôi để xác định tệp đang được chỉnh sửa. Id phần tử chỉ định yếu tố nào đã được sửa đổi.

Mặc dù ví dụ của tôi chỉ chứa một vùng có thể chỉnh sửa, mã này hỗ trợ nhiều vùng có thể chỉnh sửa trong một tệp.

Ở phía máy chủ, đây là mã PHP của tôi. Tôi đang sử dụng một khuôn khổ, vì vậy $ tôi đây -> _ POST() chức năng có thể trông hơi khác thường, nhưng hy vọng bạn sẽ có được ý tưởng:

// 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); 
    } 

Mã PHP trên là cơ bản nạp HTML, định vị div với id thích hợp, sau đó thay thế nội dung của thẻ div đó bằng nội dung được gửi qua cuộc gọi ajax. HTML sau đó được lưu lại vào máy chủ. Tôi cũng bao gồm một số mã để lưu trữ các bản sửa đổi sao lưu chỉ trong trường hợp mọi thứ đi sai lầm khủng khiếp.

Tôi nhận thấy rằng cụm từ thông dụng không phải lúc nào cũng là giải pháp tốt nhất. Trong trường hợp của tôi, thật khó sử dụng Mô hình đối tượng DOM của PHP vì nội dung HTML của tôi không phải là HTML hợp lệ. Bạn có thể xem xét sử dụng Mô hình đối tượng Dom thay vì nếu hệ thống của bạn đơn giản hơn hệ thống của tôi.

Tôi hy vọng điều này sẽ hữu ích!

+0

Cảm ơn bạn! Tôi đã tìm cách bắn một yêu cầu ajax cho việc này. Giải pháp của bạn là hoàn hảo cho việc áp dụng của tôi. – Dave

0

Sử dụng câu trả lời ở trên của @ clone45 và sửa đổi nó. Các dữ liệu sẽ được lưu busing Save nút và chỉ sau khi một số thay đổi được thực hiện đã cũ và dữ liệu mới được so sánh.

Nút lưu hiện tại được ghi đè của trình chỉnh sửa nội tuyến và được bao gồm bên dưới chỉ cảnh báo một phần câu trả lời của @ 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> 

Hy vọng điều này sẽ hữu ích !!