CKEditor 5 file manager integration sample

Play on CodePen External link All samples on CodePen External link

Read the explanation of this demo below
Demo
HTML
JavaScript
CSS
<h1 class="h5 mb-3">Flmngr: CKEditor 5 file manager</h1>

<textarea id="editor" style="height:300px"></textarea>

<div class="my-4">
  <div>
    <div class="h5 mb-2">Attached images</div>
    <div id="btn" class="btn btn-primary" style="opacity:0.2;cursor:default">Select files...</div>
    <div id="loading" style="font-size:12px">Loading file manager...</div>
    <p class="hint"><b>Hint</b>: after you selected gallery images,<br/> you can re-manage the existing gallery.</p>
  </div>
  <div id="images">
  </div>
</div>
"use strict";
ClassicEditor.create(document.querySelector("#editor"), {
    Flmngr: {
        apiKey: "FLMNFLMN",
        urlFileManager: "https://fm.flmngr.com/fileManager",
        urlFiles: "https://fm.flmngr.com/files" // demo file storage
    }
}).then((editor) => {
    editor.getFlmngr((Flmngr) => {
        // In this demo we pass Flmngr API into inner functions and callbacks.
        // You can save it somewhere and reuse without passing as an argument.
        attachOnClickListenerToButton(Flmngr);
    });
}).catch((error) => {
    console.log(error);
});
function attachOnClickListenerToButton(Flmngr) {
    let elBtn = document.getElementById("btn");
    // Style button as ready to be pressed
    elBtn.style.opacity = 1;
    elBtn.style.cursor = "pointer";
    let elLoading = document.getElementById("loading");
    elLoading.parentElement.removeChild(elLoading);
    // Add a listener for selecting files
    elBtn.addEventListener("click", () => {
        selectFiles(Flmngr);
    });
}
function selectFiles(Flmngr) {
    // Collect URLs of images of existing gallery set
    let elsExistingImages = document.querySelectorAll("#images img");
    let urls = [];
    for (let i = 0; i < elsExistingImages.length; i++)
        urls.push(elsExistingImages.item(i).src);
    Flmngr.open({
        list: urls,
        isMultiple: true,
        acceptExtensions: ["png", "jpeg", "jpg", "webp", "gif"],
        onFinish: (files) => {
            showSelectedImages(Flmngr, files);
        }
    });
}
function showSelectedImages(Flmngr, files) {
    let elImages = document.getElementById("images");
    elImages.innerHTML = "";
    for (let file of files) {
        let urlOriginal = Flmngr.getNoCacheUrl(file.url);
        let el = document.createElement("div");
        el.className = "image";
        elImages.appendChild(el);
        let elDiv = document.createElement("div");
        el.appendChild(elDiv);
        let elImg = document.createElement("img");
        elImg.src = urlOriginal;
        elImg.alt = "Image selected in Flmngr";
        elDiv.appendChild(elImg);
        let elP = document.createElement("p");
        elP.textContent = file.url;
        el.appendChild(elP);
    }
}
body {
  padding: 20px;
  background-color: #F4F4F4;
}

#images {
  margin-top: 20px;
  display: flex;
}
#images .image {
  border: 1px solid #DDD;
  box-shadow: 5px 5px 0 0 #DDD;
  background-color: white;
  padding: 10px;
  display: inline-flex;
  flex-direction: column;
  margin: 0 25px 25px 0;
  align-items: center;
}
#images .image div {
  height: 250px;
  max-width: 350px;
  text-align: center;
}
#images .image div img {
  max-height: 100%;
  max-width: 100%;
  margin: auto;
}
#images .image p {
  margin: 5px 0 0 0;
  font-size: 14px;
  color: #444;
}

.hint {
  color: #007FFF;
  font-size: 14px;
  margin-top: 10px;
  line-height: 16px;
}

.ck-editor__editable {
  min-height: 250px;
}

In this sample we show how to:

  1. Enable Flmngr file manager in CKEditor 5 after you installed the file manager.
  2. Configure paths and URLs of Flmngr inside CKEditor 5.
  3. Call Flmngr outside of CKEditor 5 (your custom external widgets).

Here is a standard practice to enable a CKEditor file manager plugin: we load the build of CKEditor 5 with Flmngr inside. Of course you can use it as a plugin too.

We pass Flmngr config section into CKEditor 5 initialization (ClassicEditor.create(element, {params}) function. CKEditor 5 will call Flmngr.load({param}) method with exactly these parameters on the initialization.

All buttons of Flmngr are already added in this build, but do not forget too specify them if loading Flmngr as a plugin.

Now CKEditor 5 is initialized and ready and you can use Flmngr there. In most cases, this is the end of the configuration of CKEditor.

But what if you want to implement some custom files field outside of CKEditor. For example you need to call Flmngr file manager to let the user pick some images from the same storage and reuse the configuration you passed into CKEditor. To do this you need to retrieve Flmngr API object from the instance of CKEditor. In this sample we have one CKEditor instance, but you can have two or more editors on the page, so they may have different initialization parameters (only apiKey parameter must be the same within one web page).

So we do it using standard CKEditor 5 API: we get an instance of CKEditor editor as the result of ClassicEditor.create async function.

At this moment in editor variable you have the instance of CKEditor 5. Let's get an instance of Flmngr API object. Use editor.getFlmngr((Flmngr) => void) function to wait for Flmngr is initialized too and passed Flmngr argument of the callback function will contain the interface with whole Flmngr API, already loaded (please do not call Flmngr.load({params}) again).'.

Now with the Flmngr API object, you can implement managing file gallery on your custom field. This is fully the same as in the Manage image gallery sample. Just attach a listener to a button of your control and call there Flmngr.open({params}) method with some parameters to let the user pick images.

We experience problems with Zendesk, our ticket system, mail sent there won't be delivered. Please write us directly to support@flmngr.com until the problem is resolved.