【问题标题】:jQuery UI, AJAX and CKEditor - CKEditor only loads the first timejQuery UI、AJAX 和 CKEditor - CKEditor 仅在第一次加载
【发布时间】:2015-03-03 16:43:03
【问题描述】:

我遇到了与herehere 报告的问题类似的问题,只是我的表单数据加载方式发生了一些变化。

第二个链接中提供的解决方案似乎解决了我的问题,但是为了使 CKEditor 正确实例化,不需要删除显示/隐藏缩放效果。解决这个冲突肯定有更好的选择。

我的问题:

当我打开我的页面并单击编辑按钮时,会弹出一个 jQueryUI 对话框,通过 ajax 加载其数据,然后我尝试用 CKEditor 实例替换添加到对话框中的文本区域。我第一次加载页面时,对话框运行顺利。我可以在编辑器中修改数据,保存表单数据,然后继续生活。但是,如果我关闭对话框,然后再次打开它,编辑器将不再启用。这些按钮仍然具有悬停效果,并且可以点击,但什么也不做。编辑器的文本区域被禁用并设置为"style: visibility: hidden; display: none;"。我能找到的关于这个问题的几乎所有信息都是多年前的,修复涉及使用不再存在或不适用的功能/技术。

控制流

我打开包含文本链接“编辑更新”的页面,该链接调用我的 Javascript 函数openEditTicketUpdateDialog

function openEditTicketUpdateDialog(tup_id, url)
    {
        simplePost(null, url, new Callback
        (
            function onSuccess(data)
            {
                $('#editticketupdatedialog').dialog('option', 'buttons',
                [
                    {
                        text: 'Save Edits',
                        click: function()
                        {
                            // Save the Update info
                            var formData = {
                                tup_update: CKEDITOR.instances.tup_update_edit.getData(),
                                tup_internal: +$('#tup_internal_edit').is(":checked"),
                                tup_important: +$('#tup_important_edit').is(":checked")
                            };

                            simplePost(formData, data['submitRoute'], new Callback
                            (
                                function onSuccess(data)
                                {
                                    $('#update-' + tup_id).html(data.input['tup_update']);
                                    $('#updateflags-' + tup_id).html(data.flags);
                                    $('#editticketupdatedialog').dialog('close');
                                },
                                function onFail(errors)
                                {
                                    console.log(errors);
                                }
                            ));
                        }
                    },
                    {
                        text: 'Cancel',
                        click: function()
                        {
                            $(this).dialog("close");
                        }
                    }
                ]);

                $('#editticketupdatedialog').dialog('option', 'title', data['title']);
                $('#editticketupdatedialog').html(data['view']);
                $('#editticketupdatedialog').dialog('open');

                destroyEditor('tup_update_edit');

                console.log('CKEDITOR.status: ' + CKEDITOR.status);
                createEditor('tup_update_edit');

            },
            function onFail(errors)
            {
                console.log(errors);
            }
        ));
    }

此函数使用三个辅助函数,simplePostdestroyEditorcreateEditor

function simplePost(data, url, callback)
{
    post(data, url, true, false, callback);
}

function createEditor(name)
{
    console.log('Create editor: ' + name);
    console.log('Current Instance: ');
    console.log(CKEDITOR.instances.name);

    if (CKEDITOR.status == 'loaded')
    {
        CKEDITOR.replace(name,
        {
            customConfig: '/js/ckeditor/custom/configurations/standard_config.js'
        });
    }
    else
    {
        CKEDITOR.on('load', createEditor(name));
        CKEDITOR.loadFullCore && CKEDITOR.loadFullCore();
    }

    console.log('After instance created: ');
    var instance = CKEDITOR.instances.name;
    console.log(instance);
}

function destroyEditor(name)
{
    console.log('Destroy editor: ' + name);
    console.log('Current Instance: ');
    console.log(CKEDITOR.instances.name);

    if (CKEDITOR.instances.name)
    {
        console.log('Instance exists - destroying...');
        CKEDITOR.instances.name.destroy();
        $('#' + name).off().remove();
    }

    console.log('After instance removed: ');
    var instance = CKEDITOR.instances.name;
    console.log(instance);
}

这种创建 CKEditor 实例的方法是从 here 收集的。这种销毁 CKEditor 实例的方法是从 here 收集的。

如您所见,openEditTicketUpdateDialog 通过 Laravel 路由触发对我的 getEditUpdateForm 函数的 AJAX 调用。

public function getEditUpdateForm($tup_id, $update_number)
{
    $update = Update::find($tup_id);

    $data = [
        'title' => 'Editing update #' . $update_number . ' of ticket #' . $update->tup_ticket,
        'view' => View::make('tickets.ticketupdate-edit')
            ->with('update', $update)
            ->render(),
        'submitRoute' => route('tickets/update/submit', $tup_id)
    ];

    return Response::json(array('status' => 1, 'data' => $data));
}

从这里返回状态 1,并调用 onSuccess 函数。我试图在$('#editticketupdatedialog').dialog('open'); 调用之前添加创建/删除调用,但无济于事。我还尝试了多种其他我发现的解决方案,其中涉及 jQueryUI 的 Dialog 函数和属性的黑客实现:_allowInteractionmoveToTop。我最初通过在执行CKEDITOR.replace之前调用此函数第一次出现此问题时成功解决了这个问题:

function enableCKEditorInDialog()
{
    $.widget( "ui.dialog", $.ui.dialog, {
    /**
    * jQuery UI v1.11+ fix to accommodate CKEditor (and other iframed content) inside a dialog
    * @see http://bugs.jqueryui.com/ticket/9087
    * @see http://dev.ckeditor.com/ticket/10269
    */
    _allowInteraction: function( event ) {
        return this._super( event ) ||

        // addresses general interaction issues with iframes inside a dialog
        event.target.ownerDocument !== this.document[ 0 ] ||

        // addresses interaction issues with CKEditor's dialog windows and iframe-based dropdowns in IE
        !!$( event.target ).closest( ".cke_dialog, .cke_dialog_background_cover, .cke" ).length;
    }
    });
}

更新到 Laravel 5 并在服务器端进行一些其他更改后,此修复不再有效。通过从我的对话框中删除显示/隐藏属性,我成功地解决了我的问题。我非常希望不必删除这些属性,因为使用对话框的一半原因是动画的美感。这是我的对话框初始化。

$('#editticketupdatedialog').dialog({
    modal: true,
    draggable: false,
    minWidth: 722,
    autoOpen: false,
    show:
    {
        effect: "scale",
        duration: 200
    },
    hide:
    {
        effect: "scale",
        duration: 200
    },
    closeOnEscape: true
});

当我启用这些动画时,我第一次使用对话框时,它工作得很好。第二次,我在JS控制台收到错误TypeError: this.getWindow(...).$ is undefined - ckeditor.js:83:18,指的是这一行:

function(a)
{
    var d = this.getWindow().$.getComputedStyle(this.$,null);

    return d ? d.getPropertyValue(a) : ""
}

回顾

我的主要目标是找到解决此问题的方法,而无需删除 jQueryUI 对话框动画。我不确定该指责谁,因为我真的无法确定问题出在 CKEditor、jQueryUI 还是我的实现上。

【问题讨论】:

    标签: ajax ckeditor jquery-ui-dialog multiple-instances jquery-effects


    【解决方案1】:

    我终于找到了适合我的解决方案。 losnir 将过时的解决方案更新为帖子 here,并将 open 函数添加到我的对话框初始化中解决了我的问题。

    我的初始化如下:

    $('#editticketupdatedialog').dialog({
        modal: true,
        draggable: false,
        minWidth: 722,
        autoOpen: false,
        show:
        {
            effect: "scale",
            duration: 200
        },
        hide:
        {
            effect: "scale",
            duration: 200
        },
        closeOnEscape: true,
        open: function()
        {
            $(this).parent().promise().done(function ()
            {
                destroyEditor('tup_update_edit');
    
                console.log('CKEDITOR.status: ' + CKEDITOR.status);
                createEditor('tup_update_edit');
            });
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多