TinyMCE file manager integration sample (with API)

Play on CodePen External link All samples on CodePen External link

Demo
HTML
JavaScript
CSS
<h1 class="h5 mb-3">Flmngr: TinyMCE file manager (with using API)</h1>

<textarea id="editor"></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";
tinymce.init({
    selector: "#editor",
    plugins: "file-manager,link,image",
    toolbar: "link | undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | outdent indent",
    Flmngr: {
        apiKey: "FLMNFLMN", // default free key
    },
    // Let's wait for TinyMCE is initialized...
    setup: (editor) => {
        editor.on('init', (event) => {
            // ...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);
    }
}
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;
}

.tox-promotion {
  display: none !important;
}

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

In this sample we show how to:

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

Here is a standard practice to enable a TinyMCE plugin: pass the name of its directory as plugins parameter on TinyMCE initialization (tinymce.init({params}) function).

Then you add a config section Flmngr in order to configure Flmngr-specific parameters. TinyMCE will call Flmngr.load({param}) method with exactly these parameters on the initialization.

Also do not forget to add the buttons of Flmngr on the TinyMCE toolbar in toolbar parameter.

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

But what if you want to implement some custom files field outside of TinyMCE. 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 TinyMCE. To do this, you need to retrieve Flmngr API object from the instance of TinyMCE. In this sample, we have one TinyMCE 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 TinyMCE API: we get an instance of TinyMCE editor in a setup callback and then wait for its initialization (to be sure the Flmngr plugin was loaded) by setting init event listener.

At this moment, in editor variable, you have the instance of TinyMCE. 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.