Question

Has anybody got any examples of using the Dynatree plugin with MVC? I have been wrestling with it without much progress. I have an action method which returns a JsonResult (but selects all columns in the underlying table, not sure if this is the problem) and in my initajax call , all I'm doing is calling this method.

If it's not too much trouble, I am looking for sample View and Controller action methods.

Thanks in advance for any help

Was it helpful?

Solution

You need to create an object to serialize the nodes eg.

public interface ITreeItem
{
}


    /// <summary>
    /// Tree Item Leaf.
    /// </summary>
    public class TreeItemLeaf :ITreeItem
    {
        /// <summary>
        /// Gets the Title.
        /// </summary>
        public string title;

        /// <summary>
        /// Gets the Tooltip.
        /// </summary>
        public string tooltip;

        /// <summary>
        /// Gets the key.
        /// </summary>
        public string key;

        /// <summary>
        /// Gets the Data.
        /// </summary>
        public string addClass;

        /// <summary>
        /// Gets the Children.
        /// </summary>
        public IList<ITreeItem> children;

        /// <summary>
        /// Gets the rel attr.
        /// </summary>
        public string rel;

        /// <summary>
        /// Gets the State.
        /// </summary>
        public bool isFolder;

        /// <summary>
        /// Gets the State.
        /// </summary>
        public bool isLazy;

        /// <summary>
        /// Initializes a new instance of the <see cref="TreeItemLeaf"/> class.
        /// </summary>
        public TreeItemLeaf()
        {
            children = new List<ITreeItem>();
        }
    /// <summary>
    /// Initializes a new instance of the <see cref="TreeItemLeaf"/> class.
    /// </summary>
    /// <param name="type">The type of node.</param>
    /// <param name="id">The Id of the node.</param>
    /// <param name="title">The Title of the node.</param>
    /// <param name="tooltip">The Tooltip of the node.</param>
    public TreeItemLeaf(String type, Guid id, String title, String tooltip)
    {
        key = id.ToString();
        this.title = title;
        isFolder = false;
        isLazy = false;
        this.tooltip = tooltip;
        children = new List<ITreeItem>();
}

}


   /// <summary>
    /// Tree Item.
    /// </summary>
    public class TreeItem : TreeItemLeaf
    {
        /// <summary>
        /// Gets the State.
        /// </summary>
        public new bool isFolder;

        /// <summary>
        /// Initializes a new instance of the <see cref="TreeItem"/> class.
        /// </summary>
        public TreeItem() : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TreeItem"/> class.
        /// </summary>
        /// <param name="type">The type of node.</param>
        /// <param name="id">The Id of the node.</param>
        /// <param name="title">The Title of the node.</param>
        /// <param name="tooltip">The tooltip of the node.</param>
        public TreeItem(String type, Guid id, String title, String tooltip) : base(type, id, title, tooltip)
        {
            isFolder = true;
            isLazy = true;
        }

    }

Once you have this, you can return a Json(IList<ITreeItem>) which you will need to build up from your results..

If you go to the Dynatee demo http://wwwendt.de/tech/dynatree/doc/samples.html , you can use Firefox/Firebug to study the HTTP requests to see exactly what is being passed in and returned.

My tree in the view is as follows :

        // --- Initialize first Dynatree -------------------------------------------
        $("#tree").dynatree({
            fx: { height: "toggle", duration: 500 },
            selectMode: 1,
            clickFolderMode: 1,
            children : @Html.Raw(String.Format("{0}", ViewData["tree"]).Replace("\"children\":[],", "")),
            onLazyRead: function (node) {
                node.appendAjax({ 
                    url: "@Url.Action("treedata", "tree")",
                    type: "GET",
                    data: { "id": node.data.key, // Optional url arguments
                        "mode": "all"
                    },
                     error: function(node, XMLHttpRequest, textStatus, errorThrown) {

                               }
                     }
                });
            }, //.... cut short for brevity

I am embeding the initial tree state in the "children:" part. And the Ajax reading is being set up in the "onLazyRead:" part.

My Ajax call is:

    public JsonResult TreeData(FormCollection form)
    {
        return GetTreeData(Request.QueryString["id"], Request.QueryString["uitype"]);
    }

The GetTreeData() function returns Json(ITreeItem);

I would recommend you use Firefox/Firebug and its "NET" function to see what is going and coming back.

Hope that helps.

OTHER TIPS

I've just found Dynatree and I'm using it on my MVC project. Here's an example of how I did it. I decided to just put the data directly in the View like the basic example.

My data is a list of cities within California, grouped by county.

My controller simply passes a view model to my View and the view model has a CitiesAvailable property:

public IEnumerable<City> CitiesAvailable { get; set; }

My list of City objects is grabbed from the database (EF4) and the actual City object is the following:

CityObject

In my View I create a ul containing the list of counties and their cities (I'm using Razor but webforms should be easy enough to figure out):

<div id="tree">
    <ul id="treedata" style="display: none;">
        @foreach (var county in Model.CitiesAvailable.Select(c => c.County).Distinct().OrderBy(c => c))
        {
            <li data="icon: 'false'">@county
                <ul>
                    @foreach (var city in Model.CitiesAvailable.Where(c => c.County == county).OrderBy(c => c.Name))
                    {
                        <li data="icon: 'false'" id="@city.Id">@city.Name</li>
                    }
                </ul>
            </li>
        }
    </ul>
</div>

Then in my JavaScript I use the following:

$("#tree").dynatree({
    checkbox: true,
    selectMode: 3,
    fx: { height: "toggle", duration: 200 }
});

It works great! Here's a sample of the output with a few items checked:

Screenshot of Dynatree result

Let me know if anything doesn't make sense.

Note, I use data="icon: 'false'" in my li elements because I don't want the icons.

You can simply convert the object to json string, and send it to server as text

this is the js code:

 var dict = $("#tree").dynatree("getTree").toDict();
 var postData = JSON.stringify(dict["children"]);
 $.ajax({ type: "POST",
                    url: "/UpdateServer/SaveUserTree",
                    data: {tree:postData},
                    dataType: "html"
                });

And this is the controller code:

 [HttpPost]
    public void SaveUserTree(string tree = "")
    {

        HttpContext.Application["UserTree"] = tree;

    }

You can send this string data back to client

   if (HttpContext.Application["UserTree"] != null)
            ViewBag.TreeData = new     HtmlString(HttpContext.Application["UserTree"].ToString());

And finally, you can initial the tree, in the View with this data:

 var treeData= @(ViewBag.TreeData)

$(function(){

    // --- Initialize sample trees
    $("#tree").dynatree({
        children: treeData
    });

});

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top