Set selected node ID to ViewModel

2 posts, 0 answers
  1. Stefan
    Stefan avatar
    1 posts
    Member since:
    Sep 2012

    Posted 11 Sep 2012 Link to this post

    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
  2. Stefan Binder
    Stefan Binder avatar
    2 posts
    Member since:
    Sep 2012

    Posted 17 Sep 2012 Link to this post

    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
Back to Top