arrow_back
TinyMCE Custom File Picker

TinyMCE Custom File Picker

As one of the most popular “what you see is what you get” plugins out there right now, the extensibility of TinyMCE cannot be understated. But one of the little niggles it comes with is the lack of a file picker, instead it requires the user to insert a URL to an image. This is hardly the definition of user friendliness.

However, it is important to note that TinyMCE comes with a built-in file picker which works hand-in-hand with MoxieManager, although you do have to fork out some cash to gain access to those features. If you plan on making extensive use of TinyMCE’s media features, it’s highly recommended that you go the route of purchasing a premium license. It comes with some nifty features too like uploading files to Microsoft Azure, Google Drive amongst others.

But what if we just want a simple file picker without all the added features? Well, we can, and it’s quite easy.

This process encompasses simply constructing or importing a file picker of our choice and calling it from an event we define on a button in our TinyMCE toolbar. Then, once the user selects an image, we direct the address of that image to be inserted into our content.

So, let us begin:

Prerequisites

  • TinyMCE Community
    • V4.6.5 was used for this tutorial
  • jQuery (needed for both TinyMCE and Boostrap’s modal component)
    • V3.2.1 was used for this tutorial
  • Bootstrap (optional, but we shall make use of its modal as a file picker for the purposes of this tutorial)
    • V4.0.0 was used for this tutorial

The HTML

The Text Editor

<textarea rows="12" class="tinymce"></textarea>

To start off, we simply create a textarea and assign a class of ‘.tinymce’ to it.

The class serves two purposes

  • to initialize our textarea with TinyMCE
  • to target this control with jQuery when we insert the image

As such, you may also make use of Ids or any other selectors for this purpose.

The File Picker

<!-- A Modal with our pictures laid out -->
<div class="modal fade" id="filePicker" tabindex="-1" role="dialog" aria-labelledby="lblFilePicker" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">

            <!-- Modal Heading amd Close Button -->
            <div class="modal-header">
                <h5 class="modal-title" id="lblFilePicker">Please Select an Image</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>

            <!-- Modal Content - Your images will go here. -->
            <div class="modal-body fileSelection">
                <img src="image1.jpg" />
                <img src="image2.jpg" />
                <img src="image3.jpg" />
            </div>
        </div> <!-- /end of modal-content -->
    </div> <!-- /end of modal-dialog -->
</div> <!-- /end of modal -->

We now go about creating our modal and populating it with images. This will server as the pop-up file picker when the user selects the option to do add an image into their content.

Again, we do not need to make use of Bootstrap’s modal, the important thing is to define all our images under a shared selector (in this case ‘.fileSelection’), and to present this to the user in an easy to navigate presentation.

For our example we have manually defined three images, but ideally in a production environment you would define code to loop through images you wish to allow the user to include, and compile them into <img> tags, these images possibly being derived from some external data source.

The jQuery code

Preparation

var activeTextArea = null;

First we need to create instances of the variables we will be using, in our case we only need one.

The purpose of this is to store the reference for the textarea which the user is currently working on. This reference will then be referred to when we need to place an instance of a selected image.

Setting up TinyMCE TextArea

tinymce.init({ 
    selector: ".tinymce", // the class of our textarea
    setup: function (editor) { 
           // on the setup of the TinyMCE plugin, add a button with the alias 'addImage' 
           editor.addButton('addImage', { 
                  text: 'Add Image', // the text to display alongside the button 
                  icon: 'image',     // the icon to display alongside the button 
                  onclick: function () { 
                           // onclick, set the active textarea to the button was pressed
                           activeTextArea = editor;
                           $('#filePicker').modal('show'); // show the file picker modal 
                  } 
           }); 
     }, 
     //include buttons on the toolbar, notice our new aliased button 'addImage' is included 
     toolbar1: 'undo redo | insert | styleselect | bold italic | addImage' 
});

An overview of what the script above does is as follows:

  • Initialize the textarea with TinyMCE
    • on setup of this textarea
      • create a custom button with the alias ‘addImage’
        • assign the text of ‘Add Image’  to this button
        • assign the icon of ‘image’ to this button (this is built into TinyMCE)
        • onClick of this button
          •  set the activeTextArea to this textarea (using the variable activeTextArea)
          • show our Bootstrap modal
      • add a toolbar to our textarea, including our new button derived from its reference of ‘addImage’

What we are trying to do is upon the initialization of the TinyMCE textarea, to create a new button with a custom function. This function being that of displaying our file picker and setting the active textarea variable to the current textarea.

From here we await input from the user, that coming into one of two responses, either they select a image (which we can now tie a function on clicking of any of them) or they cancel and the file picker simply closes. Let’s write a function for the former right now:

Inserting a Selected Image into the TextArea

$(function () { 
    $(".fileSelection img").click(function (e) { 
        activeTextArea.insertContent('&nbsp; <img src="' + $(this).attr("src") + '" /> &nbsp;'); 
        $('#filePicker').modal('hide'); 
    }); 
});

This function hooks into the images present in our file picker.

When the user clicks on any of the images present, it will take the address of that image, and insert it into the content of the textarea the user is currently working on. It then hides the file picker with the image having successfully being inserted. And just like that, it’s all done!

Final Code

Still a little confused? Take a look at a live working example over at CodePen, or alternatively, feel free to take a look at the raw code.