Question

It's kind of long but, it has pictures! :D

The one that I'm working on is some sort of real live editing which consists of preview and the editor

How it works

When I click one of the blocks that can be high lightened, the value of the block will be transferred to the ckeditor.

Here's the code that I'm working on.

I have this external.php which would be the contents of the iframe. I just chopped the code since the elements are all redundant.

<div class="container">

    <div id="block-1" class="row click">First Row</div>

    <div id="block-2" class="row click">Second Row</div>

    <div class="row">

        <div id="block-3" class="column click">
            First Column
        </div>

        <div id="block-4" class="column click">
            Second Column
        </div>
    </div>
</div>

Then I have this index.php which contains the iframe and the ckeditor.

<div id="main">

    <div id="left-col" class="col">
        <iframe src="external.php" width="500" height="600"></iframe>
    </div>

    <div id="right-col" class="col">
        <textarea name="editor" id="editor" rows="10" cols="80"></textarea>
    </div>
</div>

And for the fun part, here lies the code where it all happens

$(document).ready(function() {

    CKEDITOR.replace('editor');
    var editor = CKEDITOR.instances.editor;

    $('iframe').load(function() {

        var iframe = $('iframe').contents();

        iframe.find(".click").on("click", function(){

            var id = $(this).attr("id");
            var box_value = $(this).html();

            CKEDITOR.instances.editor.setData(box_value);

            editor.on('change', function () {
                var value = CKEDITOR.instances.editor.getData()
                iframe.find("#" + id).html(value);
            });
        });
    });
});

Here's what it looks like

enter image description here

So when I click First Row the value will be transferred into the ckeditor.

enter image description here

As the time I'm typing, the values are automatically being transferred.

enter image description here

When I click other block and try to do some live editing, the recent block that I edited also overwrites on what I'm doing on the latest block.

enter image description here

enter image description here

Until it was all covered in nooo!-es.

enter image description here

Don't you worry! I have a lead!

It seems when I alert below the ckeditor onchange event and I click one of the blocks.

enter image description here

It alerts the corresponding id on the blocks that I've clicked.

enter image description here

Yet if I put alert inside the ckeditor onchange event and click some of the blocks and try to edit it. It alerted me all the blocks that I've clicked (in order).

enter image description here

Meaning, id is somewhat being stored in ckeditor onchange event which I don't even know why.

Obviously, the problem is, when I click the block and tried to edit it, and I click different block and edit it, both blocks are being updated.

Any help would be appreciated.

Was it helpful?

Solution 3

Thanks for the people who answered here.

I totally forgot about this one, well I've already finished it last week.

Here's what I've come up with.

Note: This is not all of my code, I just chopped that includes on this problem.

I created a counter for it.

var ctr = 0;
//Editor Name counter
var editor = "e_" + ctr;

// Do create text editor
$("#editor-container").prepend("<textarea id='"+ editor +"' name='"+ editor +"' data-num='"+ ctr +"' class='text-editor' rows='10' cols='80'></textarea>");

// Do re-create CKeditor instance
if (CKEDITOR.instances[editor]) {
    delete CKEDITOR.instances[editor];
} CKEDITOR.replace(editor);

// Do check existing textarea
if (ctr > 0) {

    // Do loop textarea
    $(".text-editor").each( function() {

        var text_editor = $(this);
        var text_editor_id = text_editor.attr("id");
        ctr_editor = parseInt(text_editor.attr("data-num")) - 1;

        // Do remove recent textarea
        if (ctr_editor < ctr && ctr_editor >= 0) {
            $("#e_" + ctr_editor + ", #cke_e_" + ctr_editor ).remove();
        }
    });
}

// Do get contents of div
var default_val = contents.find(".editable[name='"+ cb +"']").html();
CKEDITOR.instances[editor].setData(default_val);

CKEDITOR.instances[editor].on("change", function() {

    var value = CKEDITOR.instances[editor].getData();
    contents.find(".editable[name='"+ cb +"']").html(value);
})

// Do increment counter
ctr++;

So when the user saves the editor using save button

/* Close editor */
$("#save-editor").on("click", function() {
    $("#editor-wrapper").animate({ width: 0 });

    // Do update editor name counter
    editor = "e_" + ctr;
    cb = "cb" + ctr;
});

OTHER TIPS

You are adding a new change event every time you click on a div. Add the change event once when the page loads. When you click on a div, set a global id variable that the change event can use.

Like @NoGray suggested you can make id global and bin the editor.onchange once

 $('iframe').load(function () {

     var iframe = $('iframe').contents();

     var id = 'someDefault';

     iframe.find(".click").on("click", function () {

         id = $(this).attr("id");
         var box_value = $(this).html();

         CKEDITOR.instances.editor.setData(box_value);
     });
     editor.on('change', function () {
         var value = CKEDITOR.instances.editor.getData()
         iframe.find("#" + id).html(value);
     });
 });

when you click on a div id copies the html into the editor and set the id of that div. this id is read when the editor changes

$(function(e){
    $("body").click(function(){
        $(".cke").each(function(){
            var idd = $(this).attr("id");
            var namme = idd.substr(4);
            var content = $("#" + idd + " iframe").contents().find('body').html();
            $("textarea[name=" + namme + "]").val(content);
        });
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top