Click here to Skip to main content
Click here to Skip to main content

Simple FileManager width MVC 3 and jsTree

, 2 Apr 2011
Rate this:
Please Sign up or sign in to vote.
In this article, I will show how easy it is to perform drag-and-drop and create operations using jsTree in a simple File Manager.

Introduction

I’ve seen several good tutorials on the net about jsTree and MVC, but they’re all somehow outdated and don’t work with jsTree’s latest version (which is a free component). It’s been a long time since I wanted to post the experience I had using jsTree (for those who don’t know what jsTree is, please go here: www.jstree.com). And what’s better to get it working than making a simple “File Manager”?

In this article, I will focus on two aspects of jsTree. The first that really blew me out was the possibility of moving trees by drag and drop, like in Windows Explorer (see Picture 1). The other feature I won’t cover (but is in the code) is using the right mouse button to display a context menu and from there create directories, rename, etc. I will not post a complete solution with rename, cut & copy features in this article, because it is just intended to be a starting point on how to use jQuery and MVC.

Picture 1: Drag and Drop

Using the code

First, we have to define our trees as JSON classes with a particular format:

public class JsTreeModel
{
    public string data;
    public JsTreeAttribute attr;
    public string state = "open";
    public List<JsTreeModel> children;
}

public class JsTreeAttribute
{
    public string id;
}

So in the data attribute, we’ll store the tree’s title, and the complete path will be stored in the ID attribute. The state of the tree will have all child leaves expanded by default, that’s what “open” is for.

We will use recursion to populate our tree, nothing really complicated.

Binding the tree

We have to use the following JavaScript to bind the tree using jQuery:

$('#MainTree').jstree({
            "json_data": {
                "ajax": {
                    "url": "/Home/GetTreeData",
                    "type": "POST",
                    "dataType": "json",
                    "contentType": "application/json charset=utf-8"
                 }
            },
            "themes": {
                "theme": "default",
                "dots": false,
                "icons": true,
                "url": "/content/themes/default/style.css"
            },

            "plugins": ["themes", "json_data", "dnd", "contextmenu", "ui", "crrm"]

        });

As you may have already understood, the “dnd” plugin stands for “Drag and Drop”.

And then the following syntax to perform the drag and drop operations:

$('#MainTree').bind("move_node.jstree", function (e, data) {
        data.rslt.o.each(function (i) {
            $.ajax({
                async: false,
                type: 'POST',
                url: "/Home/MoveData",
                data: {
                    "path": $(this).attr("id"),
                    "destination": data.rslt.np.attr("id")
                },
                success: function (r) {
                   Refresh();
                }
            });
        });
    });

On the controller side, we have to use:

[HttpPost]
public ActionResult MoveData(string path, string destination)
{
   // get the file attributes for file or directory
    FileAttributes attPath = System.IO.File.GetAttributes(path);

    FileAttributes attDestination = System.IO.File.GetAttributes(path);

    FileInfo fi = new FileInfo(path);

   //detect whether its a directory or file
   if ((attPath & FileAttributes.Directory) == FileAttributes.Directory)
    {
       if((attDestination & FileAttributes.Directory)==FileAttributes.Directory)
       {
           MoveDirectory(path, destination);
       }
    }
    else
    {
        System.IO.File.Move(path, destination + "\\" + fi.Name);
    }
    AlreadyPopulated = false;
    return null;   
}

I had to find another way to move a directory because Microsoft’s “Directory.Move” does not work in every case. Again, it’s just a starting point, it is not intended to be a complete solution.

Points of interest

One point that annoyed be a bit was the fact of having to refresh my tree in every task (move, create directory). It’s the only way I’ve found to keep sync the disk’s tree and the displayed one. Maybe some MVP could help me out if I just store the leaf’s name, I don’t know. I had to use a session state variable because otherwise if I click on the last leaf of the tree, I will have the entire tree populated again. And I couldn’t avoid it.

Anyway, I hope this article will help MVC developers wanting to use JSTree to improve the user’s experience and who don’t want to invest $500 in a professional component.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

desalbres
Software Developer (Senior) Messages S.A.S
France France
I am Web Developer at Messages, a printing company in Toulouse, France. I particularly enjoy ASP.NET MVC, JQuery, Silverlight...I have over 10 years experience in developing software, always using Microsoft Technologies.
Follow on   Twitter

Comments and Discussions

 
QuestionAdding links on nodes Pinmemberqazi nauman10-May-14 9:02 
QuestionJS Tree Not Refreshing after Creating new Node PinmemberMember 18206931-Jul-13 23:50 
AnswerRe: JS Tree Not Refreshing after Creating new Node Pinmemberdesalbres2-Jul-13 1:13 
QuestionThank you PinmemberMember 979563810-Apr-13 11:24 
SuggestionNot Using Session Variable AlreadyPopulated Pinmembersupercerealoso19-Jun-12 9:31 
GeneralRe: Not Using Session Variable AlreadyPopulated Pinmemberandrea.passadore20-Jun-12 3:31 
GeneralMy vote of 5 Pinmemberoperezcham18-Jun-12 9:02 
As a beginner with MVC 3 and jsTree, it was a great help.
QuestionWhat is the different between 'att' and 'metadata' properties of the jsTree structure? PinmemberYair Nevet19-Sep-11 5:11 
BugBug in the code? PinmemberMember 783119017-Aug-11 0:01 
QuestionGreat post! Although moving, creating and renaming does not work for me... PinmemberJaapK11-Aug-11 3:40 
AnswerRe: Great post! Although moving, creating and renaming does not work for me... PinmemberJaapK11-Aug-11 4:07 
GeneralMy vote of 5 PinmemberSangsu Park 9916-Jun-11 13:28 
GeneralGreat job - you saved me much work! PinmemberMember 13667976-Jun-11 5:42 
GeneralRe: Great job - you saved me much work! Pinmemberdesalbres6-Jun-11 7:56 
GeneralRefresh and bindings don't work PinmemberInsomniac Geek8-Apr-11 1:48 
GeneralRe: Refresh and bindings don't work Pinmemberdesalbres10-Apr-11 1:32 
GeneralRe: Refresh and bindings don't work PinmemberSiddharth_SD228-Nov-11 2:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 2 Apr 2011
Article Copyright 2011 by desalbres
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid