J_D
J_D

Reputation: 681

CKEditor 4 - Dialog/Modal position within iframe

I'm trying to position the dialog/modal window of CKEditor within my iframe but it seems to want to default to going middle center of my window. In the case of the site I'm working on, the iframe in question is 1000+ px in height, so the modal is way too far down the page and is causing confusion.

Based on this post (ckeditor dialog positioning) I have added the following code to my config file

CKEDITOR.on('dialogDefinition', function(e) {
    var dialogName = e.data.name;
    var dialogDefinition = e.data.definition;

    dialogDefinition.onShow = function() {
        var x_pos = this.getPosition().x;
        var y_pos = 10;
        this.move(x_pos, y_pos); // Top center
    };
});

Which works great on initial load, but in the case of a hyperlink in the editor, once you change the "type" (URL, email, etc) it seems that the dialog content refresh also causes a recalculation of the dialog position, which throws it back to the middle center of the window.

So bottom line is I want to make all dialogs stick to the top (maybe 20px offset) and center of my window regardless of the iframe height and have it stay there through a dialog refresh, but not finding much supporting documentation to help with that.

Example of this in action here. Click on the link icon and the dialog appears at the top of the page. Change the "type" from URL to Link and the modal will jump to the middle of the 10000 px height iframe the page is inside of

Further Edit

So the accepted answer worked perfect, but there was still an issue that the hyperlink dialog would now show all fields on initial load, and then once you changed the link type it would remove fields not related to the current selection. So looking further into the documentation, it looks like the correct way to call a dialog is as follows:

CKEDITOR.on('dialogDefinition', function(e) {
    var dialogName = e.data.name;
    var dialog = e.data.definition.dialog;

    dialog.on('show', function () {
        var x_pos = this.getPosition().x;
        var y_pos = 10;

        this.move(x_pos, y_pos); // Top center
        this._.moved = 1;
    });
});

Upvotes: 2

Views: 970

Answers (2)

user1620220
user1620220

Reputation: 1315

It looks like the dialog won't try reposition itself if the user has moved it. It tracks this using a variable called moved. You can trick it into thinking it has been moved by setting this variable to 1:

dialogDefinition.onShow = function() {
        var x_pos = this.getPosition().x;
        var y_pos = 10;
        this.move(x_pos, y_pos); // Top center
        this._.moved = 1;
    };

Note that as per this post, there are negative side-effects to overriding the onShow method that you may want to consider.

Upvotes: 2

Dekel
Dekel

Reputation: 62536

Another option (besides the one the user1620220 gave), and an option to re-set the position of the dialog even on layout change is to override the layout function of the dialog:

CKEDITOR.on('dialogDefinition', function(e) {
    var dialogName = e.data.name;
    var dialogDefinition = e.data.definition;

    // Save the old layout function
    dialogDefinition.dialog.oldLayout = dialogDefinition.dialog.layout
    dialogDefinition.dialog.layout = function() {
        // first we need to call the layout function
        dialogDefinition.dialog.oldLayout();

        // Now we can reposition the way we want:
        var x_pos = this.getPosition().x;
        var y_pos = 10;
        this.move(x_pos, y_pos); // Top center
    }

    dialogDefinition.onShow = function() {
        var x_pos = this.getPosition().x;
        var y_pos = 10;
        this.move(x_pos, y_pos); // Top center
    };
});

Upvotes: 1

Related Questions