When to use

In highly customized CKEditor 4 integrations, the next thing you might want to do is add some file or image attachments controlled by a field outside the editor.

There will be a button that opens the file manager, giving you access to the same files that the CKEditor 4 file manager provides.

How it works

An external field controlled by the CKEditor 4 file manager can be easily implemented because the CKEditor 4 plugin exposes the Flmngr file manager API, allowing you to reuse it with the same preferences as in the editor. This gives you a way to integrate Flmngr seamlessly into your CMS or app.

In your code, just make sure that CKEditor 4 is loaded, and then call the editorInstance.getFlmngr(callback) method, which will return the Flmngr API object in a callback.

You can then access this API as you wish. In this example, we illustrate the same demo of managing a set of images with the file manager.

How to start using

Run this code after a very simple installation if CKEditor 4 WYSIWYG HTML editor is already installed in your CMS or app.

The CKEditor 4 file manager plugin installs as easily as any other CKEditor add-on.

Another way to add the file manager to your app with CKEditor 4 is to install the N1ED plugin for CKEditor, which provides file manager features as well as modern Bootstrap/Tailwind block-by-block content editing and widget support.

This gives you excellent media management inside CKEditor 4, plus the ability to call the Flmngr API outside the editor.

Demo
Code
HTML
CSS
let editor = CKEDITOR.replace("editor", {
  extraPlugins: "file-manager",
  skin: "n1theme",
  Flmngr:  {
    apiKey: "FLMN24RR1234123412341234", // default free key
  }
});

// Let's wait for CKEditor is initialized...
editor.on('instanceReady', function() {
  
  // ...and get Flmngr API
  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);
    }
  )
});

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 = "";
  
  /*let elP =  document.createElement("p");
  elP.textContent = files.length + " images selected";
  elImages.appendChild(elP);*/
  
  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);
    
  }        
}
<h2 class="mb-3">Flmngr: CKEditor 4 File Manager (Using the API)</h2>

<div class="my-4">
  <div>
    <div id="btn" class="btn btn-primary btn-lg" 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 have selected gallery images,<br/> you can re-manage the existing gallery.</p>
  </div>
  <div id="images">
  </div>
</div>

<textarea id="editor"></textarea>
body {
  padding: 20px;
  background-color: #F4F4F4;
}

h2 {
  font-weight: bold;
}

#images {
  
  margin-top: 20px;
  display: flex;
  
  .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;
    
    div {
      height: 250px;
      max-width: 350px;
      text-align: center;
      
      img {
        max-height:100%; 
        max-width:100%;
        margin: auto;
      }
    }
    
    p {
      margin: 5px 0 0 0;
      font-size: 14px;
      color: #444;
    }
  }
  
}

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