ckeditor 5 toolbar link item not working in ui-dialog

Viewed 1268

I call a UI dialog box from an another UI dialog to send an email to a user listed on the first UI dialog.

This second UI dialog uses Ckeditor 5 to create the content of the email.

All of the toolbar items work perfectly, but the link icon never shows the drop down to add a URL when clicked.

I have spent a number of hours on Google and whilst I could not find an exact same scenario, there were a few articles that talked about a focus issue with the dialog and the editor, mostly in Bootstrap.

I tried to fiddle with the code given to accommodate my scenario but nothing worked.

Has anyone else come across this at all, and if so what is the solution.

Thanks in advance

5 Answers

I am also working on this issue. I managed to get the Balloon to show with .ck-balloon-panel{z-index:9999 !important} but the textbox to write the link is not selectable.

worked it out - added .ck-balloon-panel{z-index:9999 !important} so that it was always in front of anything else

try by setting modal as false

$(function () {

    $("#dialog-detail").dialog({
        autoOpen: false,
        height: 500,
        width: 700,
        modal: false,
        buttons: {
        }
    });
});

this is my solution using Jquery.

css:

.ck-balloon-panel{z-index:9998 !important}

Js:

    $("#modalId").on("click", function(){
    if($(".ck-balloon-panel").is(':visible') == true){
        setTimeout(() => {
            $(".ck-input_focused").focus()
        }, 300);
    }
})

Hope help someone, Regards!

Here a complete example. If you're using MUI in React, you can do the follow in the component that you have your CKEditor component (here I'm using React + NextJS + MUI with CKEditor DecoupledEditor). Notice that I imported GlobalStyles to override the Link baloon zIndex.

import React from "react";
import DecoupledEditor from "@ckeditor/ckeditor5-build-decoupled-document";
import { CKEditor } from "@ckeditor/ckeditor5-react";
import { Box } from "@mui/material";
import GlobalStyles from "@mui/material/GlobalStyles";

const inputGlobalStyles = (
  <GlobalStyles
    styles={{
      ".ck.ck-balloon-panel": {
        zIndex: "1400 !important", // Put a higher value that your MUI Dialog (generaly 1300)
      },
    }}
  />
);

export default function YourTextEditor({ value, onChange }) {
  let textEditor = null;

  return (
    <Box
      sx={{
        ".ck-editor__editable_inline": {
          height: "200px",
          border: (theme) =>
            theme.palette.mode === "light"
              ? "1px solid rgba(0, 0, 0, 0.20) !important"
              : "1px solid rgba(200, 200, 200, 0.25) !important",
          borderTop: "1px !important",
        },
      }}
    >
      {inputGlobalStyles}
      <CKEditor
        editor={DecoupledEditor}
        config={{
          toolbar: {
            items: [
              "bold",
              "italic",
              "underline",
              "link",
              "bulletedList",
              "numberedList",
            ],
            shouldNotGroupWhenFull: true,
          },
        }}
        data={value}
        onReady={(editor) => {
          console.log("Editor is ready to use!", editor);

          // Insert the toolbar before the editable area.
          if (editor) {
            editor.ui
              .getEditableElement()
              .parentElement.insertBefore(
                editor.ui.view.toolbar.element,
                editor.ui.getEditableElement()
              );

            textEditor = editor;
          }
        }}
        onError={(error, { willEditorRestart }) => {
          // If the editor is restarted, the toolbar element will be created once again.
          // The `onReady` callback will be called again and the new toolbar will be added.
          // This is why you need to remove the older toolbar.
          if (willEditorRestart) {
            textEditor.ui.view.toolbar.element.remove();
          }
        }}
        onChange={(event, editor) => {
          const data = editor.getData();

          onChange(data);
        }}
      />
    </Box>
  );
}

And, in the component that have the Dialog, don't forget to put the property disableEnforceFocus.

return (
    <Dialog onClose={props.onClose} open={props.open} disableEnforceFocus>...
Related