Using Bootstrap 3 Popovers With CKEditor 4 and jQu

2019-06-14 01:27发布

This is a continuation of a question I asked previously: jQuery Validate, Select2, and Bootstrap 3 Popovers - How to Bind Popover To Select2's Parent Elements Instead of Hidden Select Element

While the issue with Select2 was resolved, the issue with CKEditor never did, and while at the time I resorted to an alternate solution, I would prefer to use the popovers since they do not alter document layout when triggered.

Here is a Fiddle of my current issue: http://jsfiddle.net/jemxtthb/13/

I know it has to do with the chaining of selectors in the if statement - I put in some console output to ensure that it is triggering the popover on the CKEditor element:

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');
            }

You can see in the Elements tab in Chrome's Developer Tools that the popover is being triggered, but it ends up being in the upper left corner of the viewport. How can I attach it to the CKEditor DIV, or at least something around it like the form-group DIV surrounding it?

Oddly enough, there's no problem with the Select2 replaced element positioning; I suspect that has to do with the fact they use aria-hidden rather than the CKEditor's display: none visibility: hidden method.

Any help/advice is appreciated, and hopefully will benefit others who might be struggling with a similar issue.

1条回答
放荡不羁爱自由
2楼-- · 2019-06-14 01:53

First, only use the errorPlacement and success functions for showing/hiding and NOT the error/valid class assignments.

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");
}

Second, put everything that has to do with CSS classes into the highlight and unhighlight functions.

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');
}

Third, by commenting out the various lines above, you can see that the CSS classes have nothing to do with the placement of the popup. Your popup is appearing in the upper-left corner of the window because it's always being attached to the element being validated that's represented by element; and in the case of the CKEditor, the root element is hidden.

Since you initialize .popover() on $(element), then that's all it's ever going to do. You must initialize and show it on the visible element. In my example below, I select the immediate parent of the hidden textarea, which is $(element).parent(). Then I chained .popover('show') to the initialization...

$(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');

Then I put this inside your conditional...

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

Put all of above together, then adjust selectors and DOM traversal as you wish...

DEMO: http://jsfiddle.net/c6n30n0L/1/

查看更多
登录 后发表回答