This is a migrated thread and some comments may be shown as answers.

Set selected node ID to ViewModel

1 Answer 275 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Stefan
Top achievements
Rank 1
Stefan asked on 11 Sep 2012, 02:00 PM
Hi,

after some days of trying I finally managed to display a TreeView by transforming database entries to a treeview structure and pass it to the view inside a viewmodel.

Model:
public class LibraryTreeFormModel
{
    public int LibraryTreeNodeId { get; set; }
 
    public bool AddNode { get; set; }
    public bool DeleteNode { get; set; }
    public bool RenameNode { get; set; }
 
    public string Title { get; set; }
 
    public List<TreeNodesStruct> Tree { get; set; }
}
 
public struct TreeNodesStruct
{
    public int LibraryTreeNodeId { get; set; }
    public string Title { get; set; }
    public int? ParentNodeId { get; set; }
    public List<TreeNodesStruct> ChildNodes { get; set; }
}


View:
<% bool isCalledFirstTime = true; %>
 
 <%
     Action<List<KellyServices.Website.Areas.Admin.Models.TreeNodesStruct>> libraryTreeNodeMacros = null;
     libraryTreeNodeMacros = libraryTreeNodes =>
     { %>
            <% if (isCalledFirstTime)
               { %>
            <ul id="treeView">
            <% isCalledFirstTime = false;
               }
               else
               { %>
            <ul>
            <%} %>
            <% foreach (var c in libraryTreeNodes)
               { %>
                <li data-id="<%= c.LibraryTreeNodeId.ToString() %>"><img style="vertical-align: middle" src="<%: Url.Content("~/Content/images/filesystem_folder_yellow_small.png") %>" /> <%= Html.Encode(c.Title)%>
                <% if (c.ChildNodes != null && c.ChildNodes.Count() > 0) libraryTreeNodeMacros(c.ChildNodes);  %>
                </li>
            <% } %>
            </ul>
        <% }; %>
 
    <% var libraryTreeNodesSub = Model.Tree; %>
    <% libraryTreeNodeMacros(libraryTreeNodesSub); %>

Controller:
public TreeNodesStruct RecursiveTreeChildGetter(TreeNodesStruct root, ICollection<LibraryTreeNode> allNodes)
        {
            var childs = allNodes.Where(n => n.ParentNodeId == root.LibraryTreeNodeId);
 
            if (childs != null && childs.ToList().Count > 0)
            {
                if (root.ChildNodes == null)
                {
                    root.ChildNodes = new List<TreeNodesStruct>();
                }
 
                foreach (LibraryTreeNode child in childs)
                {
                    TreeNodesStruct treeChild = new TreeNodesStruct();
                    treeChild.ChildNodes = new List<TreeNodesStruct>();
                    treeChild.LibraryTreeNodeId = child.LibraryTreeNodeId;
                    treeChild.Title = child.Title;
                    treeChild.ParentNodeId = child.ParentNodeId;
                    root.ChildNodes.Add(treeChild);
                    treeChild.ChildNodes = RecursiveTreeChildGetter(treeChild, allNodes).ChildNodes;
                }
            }
             
            return root;
        }
 
        public ActionResult LibraryTreePartial()
        {
            List<TreeNodesStruct> tree = new List<TreeNodesStruct>();
            ICollection<LibraryTreeNode> nodes = libraryTreeNodeService.GetAllItems();
 
            var roots = nodes.Where(n => n.ParentNodeId == null);
 
            foreach (LibraryTreeNode root in roots)
            {
                TreeNodesStruct treeRoot = new TreeNodesStruct();
                treeRoot.ChildNodes = new List<TreeNodesStruct>();
                treeRoot.LibraryTreeNodeId = root.LibraryTreeNodeId;
                treeRoot.Title = root.Title;
                treeRoot.ChildNodes = RecursiveTreeChildGetter(treeRoot, nodes).ChildNodes;
                tree.Add(treeRoot);
            }
 
            var viewModel = new LibraryTreeFormModel();
            viewModel.Tree = new List<TreeNodesStruct>();
            viewModel.Tree = tree;
 
            return View(viewModel);
        }

I can get the selected node ID via javascript:
function initTreeview() {
        var treeview = $("#treeView").kendoTreeView({           
            select: function (e) { addNewNode($(e.node).data("id")); }
        });
    }

My question now is, how can I pass the selected node ID to the view model? I cannot do so in the javascript, for the model is not accessible within the script.

What I want to do is pass the selected node and the value from a textbox to the controller so that the user is able to create new subnodes. Any suggestions or workarounds?

Regards

Stefan

1 Answer, 1 is accepted

Sort by
0
Stefan Binder
Top achievements
Rank 1
answered on 17 Sep 2012, 03:34 PM
I found a working solution myself:

Keep the selected ID in a variable
<script>
var selectedTreeNode;
 
$(document).ready(function () {
        initTreeview();
    });
 
    function initTreeview() {
        var treeview = $("#treeView").kendoTreeView({           
            select: function (e) { selectedTreeNode = $(e.node).data("id"); }
        });
    }
</script>

Call javascript function on button click and pass new nodes name
<label>Title: </label>
<input type="text" name="subMenuTitle" id="subMenuTitle" />
 
<button id="btnAddNode" title="ad action">Add node</button>
 
<script>
 
    $('#btnAddNode').click(function () {
        addNewNode(document.getElementById('subMenuTitle').value);
    });
 
</script>

Call controller method to add node under selected node
    function addNewNode(title)
    {     
        $.ajax(
        {
 
            type: "POST",
            url: "<%: Url.Content("~/[Controller]/[Method]/?nodeId=") %>" + selectedTreeNode + "&nodeTitle=" + title,
            success: function(result)
            {
//                if(result.success) //do not know yet how to have the image put in the field, even json
//                {
//                    window.alert("success!");
//                }
            },               
            error : function(req, status, error)
            {
//                window.alert("Error!");  
            }
        });
    }

If I now find out how to update a partial view from the controller (just returning the partial view with the updated viewmodel in the controllers ActionResult method will not update the content) my programm is running.

Regards

Stefan
Tags
TreeView
Asked by
Stefan
Top achievements
Rank 1
Answers by
Stefan Binder
Top achievements
Rank 1
Share this question
or