How to upload images to a server and input them into tinymce version 4

By: Ryan Wong at

##My Goal:

  1. Create/Find a tinymce version 4 plugin to upload images to the server, save this image to the database and place this image in my tinymce editor

  2. This plugin must also be able to view a list of media files(image/video) that are in my database in a gallery format where the user can click an image and place it into tinymce

Some plugins I looked into are:

  • moxiemanager plugin (problem is it cost 100$ and only forfills part of what I want)
  • open manager (may have worked for tinymce version 3 but broke when I used it)
  • default image uploader (could not tag the images uploaded, had to be external sources)

After much distress, I created my own plugin.

Hopefully this will save you countless hours trying to figure out how to make an image uploader in tinymce 4.

Steps

  1. Download the latest tinymce.js file from their site.

  2. Define the textarea/element you want to run tinymce on

    1
    <textarea name='text' rows='2' id='editor' class='form-control'></textarea>
  3. Add the following to your javascript file:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $(document).ready(function() {
    tinymce.init({
    selector: "#editor",
    plugins: [
    "imageuploader"
    ],
    toolbar1: "imageuploader",
    toolbar_items_size: 'small',
    menubar: false,
    height: 800
    });

I called my plugin imageuploader and I removed all unnecessary plugins. All plugins in the toolbar or menu bar must
be in plugins.

4.Create the tinymce version 4 plugin and place it in the plugins folder inside tinymce. Call it plugin.min.js.

1
2
3
4
5
6
7
/js
/js/<vendor>
/js/<vendor>/tinymce4
/js/<vendor>/tinymce4/js
/js/<vendor>/tinymce4/js/tinymce
/js/<vendor>/tinymce4/js/tinymce/plugins/imageuploader
/js/<vendor>/tinymce4/js/tinymce/plugins/imageuploader/plugin.min.js

plugin.min.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
tinymce.PluginManager.add('imageuploader', function(editor, url) {
// Add a button that opens a window
editor.addButton('imageuploader', {
text: 'Add Media',
icon: 'image',
onclick: function() {
// Open window
editor.windowManager.open({
title: 'Select Media',
url: '/article/upload',
buttons: [{
text: 'Submit',
onclick: 'submit'
}, {
text: 'Cancel',
onclick: 'close'
}],
width: 800,
height: 600,
onsubmit: function(e) {
var newMedia = $('iframe').contents().find('#media-url');
var url = newMedia.val();
if (url.length > 0){
if (type == 'image'){
editor.insertContent('<img src="' + url + '" />');
return true;
}else if (type == 'video'){
editor.insertContent('<video autobuffer controls><source src="' + url + '" /></video>');
return true;
}
}else{
alert('something went wrong');
return false;
}
}
});
}
});


});

I’ll explain step by step.

1
tinymce.PluginManager.add('imageuploader', function(editor, url) {

This line creates the plugin in tinymce

1
editor.addButton('imageuploader', {options},{params});

This line creates a button in the toolbar where you pass in options and parameters to iframe you will open.

Some options:

1
title: 'Select Media',

Title is the title of the iframe

1
url: '/article/upload',

url is the route of the page the iframe opens.

1
2
3
4
5
6
7
  buttons: [{
text: 'Submit',
onclick: 'submit'
}, {
text: 'Cancel',
onclick: 'close'
}]

Created 2 buttons below the iframe. when either button is clicked, the iframe will close. However, you can bind submit to a function when clicked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
onsubmit: function(e) {
var newMedia = $('iframe').contents().find('#media-url');
var url = newMedia.val();
var type = newMedia.attr('data-media-type');
if (url.length > 0){
if (type == 'image'){
editor.insertContent('<img src="' + url + '" />');
return true;
}else if (type == 'video'){
editor.insertContent('<video autobuffer controls><source src="' + url + '" /></video>');
return true;
}
}else{
alert('something went wrong');
return false;
}
}

The method I used to retrieve the url from the iframe is on line 2. After you uploaded your images/video, you would
save it to a hidden input field which you will retrieve when submit button is clicked.

At this point, you can call editor.insertContent() to add it to the tinymce editor.

5.Implementing the iframe page /article/upload

On this route I created 4 screens:

  • button to show options to upload new media and button to select existing media
  • upload form for new media with additional fields I need
  • image gallery of existing media that user can include in their article
  • success page

###Page to show 2 buttons

1
2
3
4
5
6
7
8
9
10
11
<div class="col-md-12 main-button-container">
<div class="well center-block first-upload-container">
<button type="button" class="btn btn-success btn-lg btn-block" id="upload-new">
Upload New Media
</button>
<button type="button" class="btn btn-info btn-lg btn-block" id="select-media">
Select Media
</button>
</div>
</div>
<input type="hidden" name="media-url" id="media-url" data-media-type="image" data-caption=""/>

###Page to upload new media

1
2
3
4
5
6
7
8
9
10
11
<div class="col-md-12 upload-new-container">
<h3>Upload New Media File</h3>
<p>Media File</p>
<input type="file" name="mediafile-new" id="mediafile-new" />
<br/>
<p>Caption</p>
<input type="text" name="caption-new" id="caption-new" class="form-control"/>
<br/>
<button class="btn btn-block btn-success" id="upload-new-media">Upload</button>
<button class="btn btn-block btn-error" id="upload-new-cancel">Cancel</button>
</div>

###Page to select old media

1
2
3
4
5
6
7
8
9
10
11
<div class="col-md-12 select-media-viewer well center-block">
<h3 class="media-viewer-title">Media On File</h3>
<p class="media-viewer-subtext">
Please click the media you want to add to your article. Then Click use media</p>
<br/>
<div class="gallery">

</div>
<button class="btn btn-block btn-info use-media"> Use Media</button>
<button class="btn btn-block btn-error" id="use-media-cancel">Cancel</button>
</div>

I am dynamically filling gallery div with media I have and displaying them with gridify.js

###Upload file to server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var data = new FormData();
data.append('filename', $('#mediafile-new').prop('files')[0]);
$.ajax({
type: 'POST',
processData: false, // important
contentType: false, // important
data: data,
url: '/api/v1/upload',
dataType : 'text',
success: function(jsonData){
//do something
},
error: function(){
//do something
}
});

Hope this helps you out.