Click here to Skip to main content
15,880,405 members
Articles / Web Development / ASP.NET
Article

Simple FileManager width MVC 3 and jsTree

Rate me:
Please Sign up or sign in to vote.
4.83/5 (10 votes)
2 Apr 2011CPOL2 min read 89.1K   6.7K   34   20
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:

C#
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:

JavaScript
$('#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:

JavaScript
$('#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:

C#
[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)


Written By
Software Developer (Senior) Messages S.A.S
France France
I am Web Developer at Messages, a printing company in Toulouse, France. I am particularly interested about Blazor, but my primary development platform at work is ASP.NET MVC with C#. I have 15 years experience in developing software, always using Microsoft Technologies.

Comments and Discussions

 
QuestionHow can i call a java function which will return JSON string for JSTREE?? Pin
Member 1211855223-Nov-15 19:28
Member 1211855223-Nov-15 19:28 
QuestionMoveNode Not Working on Multiple Tree Pin
Member 1116227125-Sep-15 4:46
Member 1116227125-Sep-15 4:46 
QuestionAdding links on nodes Pin
qpari10-May-14 9:02
qpari10-May-14 9:02 
QuestionJS Tree Not Refreshing after Creating new Node Pin
Member 18206931-Jul-13 23:50
Member 18206931-Jul-13 23:50 
AnswerRe: JS Tree Not Refreshing after Creating new Node Pin
raphadesa2-Jul-13 1:13
raphadesa2-Jul-13 1:13 
QuestionThank you Pin
Member 979563810-Apr-13 11:24
Member 979563810-Apr-13 11:24 
SuggestionNot Using Session Variable AlreadyPopulated Pin
supercerealoso19-Jun-12 9:31
supercerealoso19-Jun-12 9:31 
GeneralRe: Not Using Session Variable AlreadyPopulated Pin
andrea.passadore20-Jun-12 3:31
andrea.passadore20-Jun-12 3:31 
GeneralMy vote of 5 Pin
operezcham18-Jun-12 9:02
operezcham18-Jun-12 9:02 
QuestionWhat is the different between 'att' and 'metadata' properties of the jsTree structure? Pin
Yair Nevet19-Sep-11 5:11
Yair Nevet19-Sep-11 5:11 
BugBug in the code? Pin
Member 783119017-Aug-11 0:01
Member 783119017-Aug-11 0:01 
QuestionGreat post! Although moving, creating and renaming does not work for me... Pin
JaapK11-Aug-11 3:40
JaapK11-Aug-11 3:40 
AnswerRe: Great post! Although moving, creating and renaming does not work for me... Pin
JaapK11-Aug-11 4:07
JaapK11-Aug-11 4:07 
GeneralMy vote of 5 Pin
Sangsu Park 9916-Jun-11 13:28
Sangsu Park 9916-Jun-11 13:28 
GeneralGreat job - you saved me much work! Pin
Nick Van Tassell6-Jun-11 5:42
Nick Van Tassell6-Jun-11 5:42 
GeneralRe: Great job - you saved me much work! Pin
raphadesa6-Jun-11 7:56
raphadesa6-Jun-11 7:56 
GeneralRefresh and bindings don't work Pin
MagnusJohansson8-Apr-11 1:48
MagnusJohansson8-Apr-11 1:48 
GeneralRe: Refresh and bindings don't work Pin
raphadesa10-Apr-11 1:32
raphadesa10-Apr-11 1:32 
GeneralRe: Refresh and bindings don't work Pin
Siddharth_SD228-Nov-11 2:12
Siddharth_SD228-Nov-11 2:12 
GeneralRe: Refresh and bindings don't work Pin
Member 1056472824-Aug-16 16:08
Member 1056472824-Aug-16 16:08 

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

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