使用 Bootstrap 3 个弹出框与 CKEditor 4 和 jQuery 验证

Using Bootstrap 3 Popovers With CKEditor 4 and jQuery Validate

这是我之前提出的问题的延续:

虽然 Select2 的问题已解决,但 CKEditor 的问题从未解决,虽然当时我求助于替代解决方案,但我更愿意使用弹出窗口,因为它们在触发时不会改变文档布局。

这是我当前一期的 Fiddle:http://jsfiddle.net/jemxtthb/13/

我知道它与 if 语句中的选择器链接有关 - 我输入了一些控制台输出以确保它触发 CKEditor 元素上的弹出框:

if (element.is(':hidden')) {
                $(element).siblings().next().popover('show').parents('.form-group').addClass('has-error').removeClass('has-success');
                    console.log('hidden element');
             } else {
            $(element).popover("show").parents(".form-group").addClass('has-error').removeClass('has-success');
                console.log('normal element');
            }

您可以在 Chrome 的开发人员工具的“元素”选项卡中看到正在触发弹出窗口,但它最终位于视口的左上角。我怎样才能将它附加到 CKEditor DIV,或者至少像它周围的 form-group DIV 一样?

奇怪的是,Select2替换元素定位没有问题;我怀疑这与他们使用 aria-hidden 而不是 CKEditor 的 display: none visibility: hidden 方法有关。

感谢任何help/advice,并希望对可能遇到类似问题的其他人有所帮助。

首先,仅将 errorPlacementsuccess 函数用于 showing/hiding 而不是 error/valid class 赋值。

errorPlacement: function(error, element) {  // <- SHOW the tooltip

    var lastError = $(element).data('lastError'),
        newError = $(error).text();

    $(element).data('lastError', newError);

    if (newError !== '' && newError !== lastError) {
        $(element).popover({
            trigger: "manual",
            placement: "auto top",
            content: newError,
            container: "body",
            template: "<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><div class=\"popover-content\"><p></p></div></div>"
        });
        $(element).popover('show'); 
    }
},
success: function(label, element) {   // <- HIDE the tooltip
    $(element).popover("hide");
}

其次,将与CSSclass有关的所有内容都放入highlightunhighlight函数中。

highlight: function(element) {
    $(element).parent(".form-group").addClass('has-error').removeClass('has-success');
},
unhighlight: function(element) {
    $(element).parent(".form-group").removeClass('has-error').addClass('has-success');
}

第三,通过注释掉上面的各行,可以看到CSSclass这几行与弹窗的放置无关。您的弹出窗口出现在 window 的左上角,因为它始终附加到由 element 表示的正在验证的元素;对于 CKEditor,根元素是隐藏的。

既然您在 $(element) 上初始化了 .popover(),那么这就是它要做的全部。 您必须初始化并显示在可见元素上。在我下面的示例中,我 select 是隐藏 textarea 的直接父级,即 $(element).parent()。然后我将 .popover('show') 链接到初始化...

$(element).parent().popover({
    trigger: "manual",
    placement: "auto bottom",
    content: newError,
    container: "body",
    template: "<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><div class=\"popover-content\"><p></p></div></div>"
}).popover('show');

然后我把它放在你的条件中...

if ($(element).is(':hidden')) {
    $(element).parent().popover({....}).popover('show');
} else {
    $(element).popover({....}).popover('show');
}

将以上所有内容放在一起,然后根据需要调整 selectors 和 DOM 遍历...

演示:http://jsfiddle.net/c6n30n0L/1/