Использование jQuery для извлечения контента из iframe CKEditor - PullRequest
24 голосов
/ 29 мая 2009

У меня есть пользовательская CMS, которая использует CKEditor * (FCKEditor v3) для редактирования контента. Я также использую плагин jQuery Validation , чтобы проверить все поля на наличие ошибок перед отправкой на основе AJAX. Я использую функцию serialize () для передачи данных в бэкэнд PHP.

Проблема в том, что serialize удается правильно захватить все поля, кроме фактического содержимого, набранного в CKEditor. Как и любой другой редактор WYSIWYG, этот также накладывает iframe поверх существующего текстового поля. И сериализация игнорирует iframe и ищет только текстовое поле для содержимого, которое, конечно, не находит, возвращая пустое тело содержимого.

Мой подход к этому состоит в том, чтобы создать перехват для события CKEditor onchange и одновременно обновить текстовое поле (CKEDITOR.instances.[textboxname].getData() возвращает содержимое) или какое-либо другое скрытое поле с любым изменения, внесенные в редакторе.

Однако, поскольку CKEditor все еще находится на стадии бета-тестирования и остро не хватает документации, я не могу найти подходящий вызов API, который позволил бы мне это сделать.

Кто-нибудь знает, как это сделать?

Ответы [ 12 ]

34 голосов
/ 05 января 2010

Другим общим решением для этого будет запускать следующее всякий раз, когда вы пытаетесь отправить форму

for ( instance in CKEDITOR.instances )
            CKEDITOR.instances[instance].updateElement();

Это заставит все экземпляры CKEDITOR в форме обновить свои соответствующие поля

7 голосов
/ 25 ноября 2009

Я только что выпустил плагин CKEditor для jQuery, который позаботится обо всем этом в фоновом режиме без дополнительного кода: http://www.fyneworks.com/jquery/CKEditor/

6 голосов
/ 24 сентября 2009

Я также пытался решить эту проблему сегодня. Я понял, что причина, по которой приведенный выше код не работает для меня, заключается в том, что экземпляр CKEditor еще не готов, когда на него ссылается свойство документа. Таким образом, вы должны вызвать событие «instanceReady», и внутри него можно использовать события документа, потому что до этого он просто не существовал.

Этот пример может работать для вас:

CKEDITOR.instances["editor1"].on("instanceReady", function()
{
//set keyup event
this.document.on("keyup", CK_jQ);

 //and paste event
this.document.on("paste", CK_jQ);
});

function CK_jQ()
{

    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
}
3 голосов
/ 29 мая 2009

Это должно сделать это ...

CKEDITOR.instances["editor1"].document.on('keydown', function(event)
{
    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
});

CKEDITOR.instances["editor1"].document.on('paste', function(event)
{
    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
});

edit: добавлен раздел для обновления текстового поля после вставки, тоже ...

2 голосов
/ 13 марта 2010

У меня был успех с этим:

console.log(CKEDITOR.instances.editor1.getData());
1 голос
/ 23 июля 2011

CKEDITOR.instances.wc_content1.getData() вернет данные ckeditor
CKEDITOR.instances.wc_content1.setData() установит данные ckeditor

1 голос
/ 17 февраля 2011

Событие contentDom сработало для меня, а не для instanceReady ... Мне бы очень хотелось знать, что это за события, но я предполагаю, что они являются частными ...

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

CKEDITOR.instances.editor.on("instanceReady", function(){
    this.on('contentDom', function() {
        this.document.on('keydown', function(event) {
            CKEDITOR.tools.setTimeout( function(){ 
                $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
            }, 1);
        });
    });
    this.on('contentDom', function() {
        this.document.on('paste', function(event) {
            CKEDITOR.tools.setTimeout( function(){ 
                $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
            }, 1);
        });
    });
    edits_clix();
    var td = setTimeout("ebuttons()", 1);
})
1 голос
/ 13 апреля 2010

Не лучше ли сделать это так:

CKEDITOR.instances.editor1.on('contentDom', function() {
          CKEDITOR.instances.editor1.document.on('keyup', function(event) {/*your instructions*/});
        });

ref: http://cksource.com/forums/viewtopic.php?f=11&t=18286

1 голос
/ 18 декабря 2009

Я выбрал немного другой подход, я подумал, что было бы лучше использовать функцию обновления ckeditor, и поскольку использовалась keyup, тайм-аут не был необходим

CKEDITOR.instances["editor1"].on("instanceReady", function()
{
//set keyup event
this.document.on("keyup", CK_jQ);

 //and paste event
this.document.on("paste", CK_jQ);
}

function CK_jQ()
{
   CKEDITOR.instances.editor1.updateElement(); 
}
0 голосов
/ 17 января 2012

Я решил эту проблему с текущей версией: http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js

После строка 55 this.submit (функция (событие) { - я добавил этот код:

if (typeof CKEDITOR !== "undefined") {
    for ( instance in CKEDITOR.instances )
        CKEDITOR.instances[instance].updateElement();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...