You are hereBlogs / rahul's blog / ExtJsFileManager - ExtJs based File and Image Manager plugin for TinyMCE

ExtJsFileManager - ExtJs based File and Image Manager plugin for TinyMCE


rahul's picture

By rahul - Posted on 08 May 2011

A couple of days ago, I started implementing a rather interesting piece of code. It was late into the night, and I was not feeling like doing my regular work and neither was I sleepy. At that time, I was reminded of another project where we needed to provide users the ability to browse and upload files while entering content through the WYSIWYG editor we would provide them.

Basically the project was an eLearning web portal and users needed the ability to enter content through a WYSIWYG editor, upload files through the editor itself, browse the files on the server and further select image/media files on the server to insert them inline into the Html content in the editor. In short, they needed a kind of Image, Media and File Manager to integrate and operate seamlessly from the WYSIWYG editor.

Although I have used many of them earlier, TinyMCE has been my WYSIWYG editor of choice lately. I quickly checked the plugins for the latest version of TinyMCE and it does not ship with such a File Manager natively. However I noticed 2 related commercial plugins from the TinyMCE creators themselves. After some thought, I decided to implement the plugin myself as I was not sure that the functionality I needed would be available exactly from the commercial plugins. I needed the plugin to work exactly like my specifications. So, I spent late Thursday night and bulk of today (Sunday) coding the plugin and I have been really pleased on how it has shaped up. So much so, that I decided to share the plugin with the community Cool...

So, let's now discuss somethings about the plugin itself. This plugin is based on ExtJs 4.x for TinyMCE 3.x.

We were using ExtJs 4 in UI for this eLearn Portal already. So, ExtJs was the natural choice when it came to using the Tree, Grid and other components that would be required for a FileManager/FileBrowser kind of a plugin. The major challenge was not so in coding the FileManager/Browser functionality with ExtJs but more with understanding how plugins work in TinyMCE (mind you, this was my first attempt at a TinyMCE plugin) and making ExtJs and TinyMCE integrate seamlessly.

ExtJs File Manager ButtonsThe first challenge was getting multiple buttons on the TinyMCE toolbar. It took me some time to figure out that you specify each button offered by a TinyMCE plugin independently in the theme_advanced_buttonsx configuration to the TinyMCE init method. This plugin adds 4 buttons (as you can see above in the screenshot), one for selecting images from the server to be inserted inline, second for selecting media files, third for uploading files and the last one is an info button for the plugin. Please note that the button for selecting Media files would be available only if the TinyMCE editor instance has the media plugin enabled for it, otherwise the button for selecting Media files would not show up on the toolbar. All the rest 3 buttons are always available irrespective of the plugins you have enabled for the TinyMCE editor instance.

I have used regular ExtJs window, TreePanel and GridPanel for the bulk of UI compromising the facilities for selecting files from the server and uploading them (as you can see in the screenshots below).

ExtJs File Manager UI  You can upload a file  4 files can be uploaded at a time

Having done this, the next important piece of the puzzle was how to get the user to enter the auxiliary information for the Images/Media files selected from the server (title, width, height etc). My initial instinct was to create custom UI for it in ExtJs. But then I thought there is no point re-inventing the wheel and it would be better to re-use the dialogs available from TinyMCE itself for the purpose.

The native Tiny MCE dialogs are shown for entering additional information on selected filesSo, after you select an Image file from the server, the ExtJs Browser plugin checks if the Advanced Image plugin is enabled for the editor instance. If its available, the Advanced Image popup is shown where the url to the image is already filled-in, you can see its Preview and add other information about the image. If Advanced Image plugin is not available, the basic Image pop-up is shown.

The ExtJsFileManager works with and without inline pop-ups for the TinyMCE Editor.

Similar thing happens for the Media selection button. You can browse and select the Media file from server and then the Media popup is shown to request further information about the selected Media file (this button as mentioned, is available only if Media plugin is enabled for the Tiny MCE editor instance).

So, that are some details on how this plugin for Tiny MCE works. Let's now take a look at how to use this plugin. Following is a sample configuration to use this plugin:

 

tinyMCE.init({
    // General options
    mode: "exact",
    elements: "txt1",
    theme: "advanced",
    skin: "o2k7",
    plugins: "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,advlist,autosave,extjsfilemanager",

    // Theme options
    theme_advanced_buttons1: "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
    theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
    theme_advanced_buttons3: "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
    theme_advanced_buttons4: "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak,restoredraft,|,extjsfilemanagerselectimage,extjsfilemanagerselectmedia,extjsfilemanagerupload,extjsfilemanagerinfo",
    theme_advanced_toolbar_location: "top",
    theme_advanced_toolbar_align: "left",
    theme_advanced_statusbar_location: "bottom",
    theme_advanced_resizing: true,

    //ExtJs FileManager options
    //Required - Server url handling the requests
    extjsfilemanager_handlerurl: 'BrowserHandler.ashx',
    //Optional - Any extra parameters you want to have passed to your server-side handler on each request from the FileManager.
    extjsfilemanager_extraparams: { param1: 'value1', param2: 'value2' }
});

There are 2 configuration options for this plugin:

  1. The handler url which would be responsible for handling all calls for fetching files, directories etc. for this plugin (samples for both ASP.NET and PHP are attached below). This is a required option.
  2. Any additional parameters you want to be sent to the server on each request by this plugin. This is an optional configuration for the plugin.

A good thing about this plugin is it does not assume anything on what's happening on the server-side. So, if you want different files or directories to be shown depending upon the user or his/her roles, you do it completely server-side and send the accessible files/folders to the browser which this plugin then presents to the user to select from.

Further you can control which buttons are shown to the current user. e.g. if you want the current user to be only able to browse files from the server but not upload files, simply omit the Upload button from the configuration (whose key is extjsfilemanagerupload). Then you will need to take care on the server to reject the upload request if an unauthorized user tries to act smart and craft a manual upload request to the server.

But again, all this is handled server-side and you can use this plugin as a stand-alone interface on client-side to allow user to browse, select and/or upload images and media files from the server. And you can easily restrict in your server code which files and directories a user has access and can browse/upload to.

You will find 3 files attached below:

  1. extjsfilemanager.zip - This is the raw plugin code for TinyMCE that you drop to your TinyMCE's plugins folder.
  2. The second is a complete sample application in .NET. You just download and extract it and run it over IIS, it comes bundled with ExtJs 4 and TineMCE 3, so no additional downloads would be required.
  3. The third is a complete sample application in PHP. Again, you just download and extract it and run it over Apche (or IIS), and it also comes bundled with ExtJs 4 and TineMCE 3.

If I get time, I would try to further enhance this plugin to a FileManager beast, something like my Take Control module for Drupal (but no promises, and it depends upon if I get time to work further on this plugin). In the meantime, the plugin in its present form should already satisfy many of the use-cases and should be a good alternative to the commercial counterparts from TinyMCE authors (no prizes for guessing, this plugin is totally free).

 

 

AttachmentSize
extjsfilemanager.zip20.56 KB
extjsfilemanager - ASP.NET Sample application1.33 MB
extjsfilemanager - PHP Sample application1.33 MB

Hi, Nice job, thanks for your efforts, and the inspiration.

I found one thing: in fullscreen mode the Plugins Browser Window couldn't be see, because of the z-index differences between the Ext.Window and the TinyMCE fullscreen editor.

My workaround is this little ExtJs trick to set the base z-index high enough:

Ext.WindowMgr.zseed = 300000; (at the end of your Test.js file)

Thanks again:
Balint

rahul's picture

Hi Balint, thanks for sharing your issue and the solution :)

I would like to say thank you about your project. This very useful and readly had a  nice screen.

Current using is dot net version, it's okay.

jackie Tân.

Hi Rahul,

your file managing plugins are Ext4 based. Which plugin do you use for the TinyMCE? I am only aware of the Ext3 TinyMCE Plugin (link).

Björn

rahul's picture

Hi Bjorn, I think you misread the blog post. It is not about integrating TinyMCE with ExtJs 4. Rather this blog post is about a File and Image Manager plugin for TinyMCE which uses ExtJs 4 inside the TinyMCE plugin.

This means that the TinyMCE itself is not placed within an Ext 4 form?

rahul's picture

Nopes!!

All right, thanks for your info!

Björn

Hello, nice job..

I downloaded the asp.net project ... What i want is to use the .net projec as an external application. So i include the js links in my project and i see the editor and i can upload files.

but ... when i click the image button i'm getting an error

i notcied that i'm getting nulls for

string op=context.Request["op"];
string path=this.context.Request["path"];

so is it possible to use this project as an external application???
rahul's picture

I am not sure what you mean by external application. But yes, its possible to use this across multiple IIS Virtual directories (IIS 6 and earlier) or IIS applications (IIS 7 and later). Some tweaks like changing web-service paths would be required for javascript Ajax calls I think.

yes.. I have a my project .. and i want to point all js links to your .net project and use the tinymce with the editor .. I already integrated but as i said there are some issues ... Can you tell which web-service paths i need to change in order to use this as an external app.

thanks i advance

rahul's picture

If the ASP.NET app housing this plugin is in a different IIS application than your project, then in resources\js\Test.js, you would need to update the handler url and give a fully-qualified url to the location of BrowserHandler.ashx:

    extjsfilemanager_handlerurl: 'BrowserHandler.ashx',

I already did that but no success. I run your .net project in the iis. I run my application on iis to. I change the when I init the tinymce in my app i set the url of "Your" applicationto reference the "BrowserHandler.ashx" file. but no success.

So please , can you give me any suggestion.

This is the scenario: "I have my application in iis in one domain (ex, localhost:150)" ...

I host your app in iis with another domain(localhost:200) and i want to use the tinymce editor using your application

rahul's picture

Hi Lazar, I donot think that is possible at all. I assume you meant that you have already updated the handler_url to point to the IIS app running the TinyMce plugin project. But even then, you are changing the ports. And that brings in Browser's same-origin sandboxing checks. I believe all ajax calls from the app with one port to the app with the second port would be failing.

If you want this to work, you should run the 2 apps from the same domain, port and protocol. The only thing you can change is the path of the application or else browsers wont allow using XmlHttpRequest between the 2 urls.

Hello,

I am still having  a few issues with the Extjs File Manager. The tinyMCE plug in is excellent, but I was wonderingw whether it would be possible to change the $base values in the BrowserHandler.php file.

I am wanting to be able to be able to provide a unique folder to a user so that other users would not be able to see their foldes on the hosting server.

I have tried changing the $base variable as in the example below and it produces the error below.

function validatePath ($path)
{
    // The parent directory of this file is the application root for this test application.
    $basePath =joinPaths(dirname(__FILE__), 'Uploads/test');
        //$basePath ='Uploads';

An uncaught error was raised: "You're trying to decode and invalid JSON String: <br />
<b>Warning</b>:  opendir(opt/lampp/htdocs/ejs/Uploads/test) [<a href='function.opendir'>function.opendir</a>]: failed to open dir: No such file or directory in <b>/opt/lampp/htdocs/ejs/BrowserHandler.php</b> on line <b>63</b><br />
[]". Use Firebug or Webkit console for additional details.

I am currently developing the web application on Ubuntu. I have checked the php settings and cannot find any reference to the Uploads folder. Obviously there is a path variable at the start of the BrowserHandler.php file, but this appears to have a Null value.

Hope you can help with this.

Regards
Steve

rahul's picture

Hi Steve,

Well I do not have time to look at the code but you can easily do what you want in server side code. If you want to have user-specific folders, then simply use something like this:

$base = 'Uploads/' . $username;

(Replace $username with an id, or any other user specific information according to your application design). The corresponding folder should exist or you would get an error.

Hello,

I had tried this previously and it does work fine, but the base folder is listed underneath the Uploads folder and not as the root of the folder tree. This means that any other folers directly underneath the Uploads folder are displayed.

Sorry to bother you with this, but really want to use this plugin as it is the best i've seen.

Thanks
Steve

rahul's picture

Hi Steve, you can easily manipulate the base folder to be the root or some levels down. The point is this is controlled by your server-side code and you wont need to change javascript plugin for it.

You define your folder structure in php and the plugin displays only the data returned from server, so you can re-organize your folder structure server side or else use filtering based on switch/if statements or regex to send sub-folders selectively to the plugin on browser side.

Hello Rahul,

All sorted now, many thanks for your help.

Steve

Hello Rahul, I have integrated this to my web system. It works normal on localhost. But don't work on server.

I see this page so long time: Please wait... when click Upload files=>Upload directory

How to solve it?
Bayaraa

AttachmentSize
error.jpg 11.99 KB
rahul's picture

Hi Bayaraa, please ensure that the handler url points to a correct location:

extjsfilemanager_handlerurl: 'BrowserHandler.ashx',

Apart from that, its difficult to guess without having a look at the installation.

Thank you for your reply.

I have checked extjsfilemanager_handlerurl and this is correct.

My web solutions structure is shown below pic.

Please you see this structure and assist me about this architecture of integration?

Thank you.

Bayaraa

AttachmentSize
tree.txt 48.19 KB
rahul's picture

Hi Bayaraa, I still think its an issue with handler url. I do not see BrowserHandler.ashx in your directory structure. There's one FileManagerHandler.ashx for which you need to set the url to Handlers/FileManagerHandler.ashx (or whatever else correctly resolves to your handler url).

Problem solved. I think what there was 2 problems.

  1. hanlder_url path is incorrect.
  2. Web browser have cached. So I didn't see my changes.

Thank you.

rahul's picture

Thanks for letting us know bayaraa...

Hello Rahul,

ext-all.css conflicted with other my website css files.

I have searched so many and found this configuration (Ext.scopeResetCSS=true;).

Where use this configuration and how to solve my css conflict problem by another way?

rahul's picture

Hi bayaraa, that is outside the scope of this blog post. I would not be able to help in that context. A better place to seek help might be ExtJs forums.

it is good example thank you

Hi, Thanks for your lovely code.

Thank you very much !! ,  I have been searching for such a plugin a couple of hours, thanks a lot

Post new comment

The content of this field is kept private and will not be shown publicly.

Recent comments