【发布时间】:2015-03-03 16:43:03
【问题描述】:
我遇到了与here 和here 报告的问题类似的问题,只是我的表单数据加载方式发生了一些变化。
第二个链接中提供的解决方案似乎解决了我的问题,但是为了使 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);
}
));
}
此函数使用三个辅助函数,simplePost、destroyEditor 和 createEditor。
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 函数和属性的黑客实现:_allowInteraction 和 moveToTop。我最初通过在执行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