[CLOSED] TreeGrid with treestore

  1. #1

    [CLOSED] TreeGrid with treestore

    Hi,

    I'm using a treepanel with treestore and also ajax proxy to load the same. I need a way to send back the new and dirty nodes/records back to the controller.

    In normal store we usually send store.getChangedData() and receive it in controller by StoreDataHandler.

    But for tree store, I tried with getNewRecords but I'm not sure how to recieve it in controller. When I tried to receive it as just object , it is getting there but i'm not able to deserialize it.

    I would like to know how I can achieve this in TreeStore. Also is there a way to get new, modified and deleted records at once like getchangedData of store?

    Thanks!
    Last edited by fabricio.murta; Sep 02, 2015 at 4:16 PM. Reason: [CLOSED]
  2. #2
    Hi @vmehta,

    It appears that a TreeStore's .getChangedData() works for new and deleted records.

    However, it doesn't work for edited records. Most likely, because of this issue:
    https://www.sencha.com/forum/showthread.php?291675

    As a workaround for now, I can suggest to try a CellEditing's Edit handler:
    .Handler = "e.record.dirty = true;"
    As for StoreDataHandler, I am not sure it is going to work with a data returned by TreeStore's .getChangedData(), because as far as I can remember it was designed for a regular Store. But you can give it a try.
  3. #3
    Hi Danil,

    Thanks for the reply. getChangedData works for tree . But the problem is if a parent node is modified I want all its child nodes also. Is there a way to get that ? Or Please suggest me a better way to achieve this.

    Thanks!
  4. #4
    I am working on a sample and hope to post it later this week.
  5. #5
    Here is an example. Please have a look.

    View
    @{
        var X = Html.X();
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Ext.Net.MVC v3 Example</title>
    
        <script>
            // Just creating a new node for testing
            var create = function () {
                var destinationNode = App.TreePanel1.store.getRootNode();
    
                destinationNode.appendChild({
                    text: "New Node",
                    leaf: true
                });
            };
    
            // Just removing some node for testing
            var remove = function () {
                var node = App.TreePanel1.store.getRootNode().childNodes[3];
    
                node.remove();
            };
    
            var saveChangedData = function () {
                var tree = App.TreePanel1,
                    treeStore = tree.getStore(),
                    removedRecords = treeStore.getRemovedRecords(),
                    updatedRecords = treeStore.getUpdatedRecords(),
                    newRecords = treeStore.getNewRecords(),
                    changedData = {};
    
                if (newRecords.length > 0) {
                    changedData.Created = [];
    
                    Ext.Array.each(newRecords, function (node, index) {
                        changedData.Created.push(tree.convertToSubmitNode(node, { withChildren: true }));
                    });
                }
    
                if (removedRecords.length > 0) {
                    changedData.Deleted = [];
    
                    Ext.Array.each(removedRecords, function (node, index) {
                        changedData.Deleted.push(tree.convertToSubmitNode(node, { withChildren: true }));
                    });
                }
    
                if (updatedRecords.length > 0) {
                    changedData.Updated = [];
    
                    Ext.Array.each(updatedRecords, function (node, index) {
                        changedData.Updated.push(tree.convertToSubmitNode(node, { withChildren: true }));
                    });
                }
    
                if (!Ext.Object.isEmpty(changedData)) {
                    App.direct.SaveChangedData(changedData);
                } else {
                    Ext.Msg.alert("Info", "No changed data for saving");
                }
            };
        </script>
    </head>
    <body>
        @X.ResourceManager()
    
        @X.Button().Text("Create").Handler("create")
    
        @X.Button().Text("Remove").Handler("remove")
    
        @X.Button().Text("Save changed data").Handler("saveChangedData")
    
        @(X.TreePanel()
            .ID("TreePanel1")
            .Title("Tree")
            .Width(200)
            .Store(
                X.TreeStore()
                    .Proxy(
                        X.AjaxProxy().Url(Url.Action("GetChildren"))
                    )
            )
            .Root(
                X.Node().NodeID("0").Text("Root").Expanded(true)
            )
            .Editor(X.TextField())
            .Plugins(X.CellEditing()
                .Listeners(events =>
                    events.Edit.Handler = "e.record.dirty = true;"
                )
            )
        )
    </body>
    </html>
    Controller
    [DirectController]
    public class RazorController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public StoreResult GetChildren(string node)
        {
            NodeCollection nodes = new Ext.Net.NodeCollection();
    
            if (!string.IsNullOrEmpty(node))
            {
                for (int i = 1; i < 6; i++)
                {
                    Node asyncNode = new Node();
                    asyncNode.Text = node + i;
                    asyncNode.NodeID = node + i;
                    nodes.Add(asyncNode);
                }
    
                for (int i = 6; i < 11; i++)
                {
                    Node treeNode = new Node();
                    treeNode.Text = node + i;
                    treeNode.NodeID = node + i;
                    treeNode.Leaf = true;
                    nodes.Add(treeNode);
                }
            }
    
            return this.Store(nodes);
        }
    
        [DirectMethod]
        public ActionResult SaveChangedData(string changedDataJson)
        {
            TreeStoreChangedData changedData = JSON.Deserialize<TreeStoreChangedData>(changedDataJson);
    
            string message = "";
    
            if (changedData.Created != null)
            {
                message += "Created nodes count: " + changedData.Created.Count + "<br>";
            }
            else
            {
                message += "Created nodes count: 0<br>";
            }
    
    
            if (changedData.Deleted != null)
            {
                message += "Deleted nodes count: " + changedData.Deleted.Count + "<br>";
            }
            else
            {
                message += "Deleted nodes count: 0<br>";
            }
    
            if (changedData.Updated != null)
            {
                message += "Updated nodes count: " + changedData.Updated.Count + "<br>";
            }
            else
            {
                message += "Updated nodes count: 0<br>";
            }
    
            X.Msg.Alert("SaveChangedData", message).Show();
    
            return this.Direct();
        }
    }
    TreeStoreChangedData Class
    public class TreeStoreChangedData
    {
        public List<SubmittedNode> Created { get; set; }
        public List<SubmittedNode> Deleted { get; set; }
        public List<SubmittedNode> Updated { get; set; }
    }
    The example is not full. You should handle a batch save request in a similar way that it is done for a regular Store. Please see the BatchController in this example.
    http://mvc.ext.net/#/GridPanel_Update/Batch
  6. #6
    Thanks a lot Daniil. Your example works for me. But I'm not able to access App.direct.SaveChangedData instead called via direct event by passing changedData as an extra params. It gives the direct children of a node but not children's children . I mean it does not give the nodes recursively to the controller.

    Is that the expected behavior?? I see , this is because of the below line we do.
    Ext.Array.each(removedRecords, function (node, index) {
    changedData.Deleted.push(tree.convertToSubmitNode( node, { withChildren: true }));
    });
    may be we can tweak this to behave recursively to get all the nodes. Currently I'm taking care of the recursive nodes in server side.

    I need to know is there an in built way to get all the nodes recursively to the server. ?

    Thanks!
    Last edited by vmehta; Aug 26, 2015 at 9:05 AM.
  7. #7
    Oh, I just found out that you edited the initial post. There is no notifications on editing. So, if you add new information, it is better to create a new post. In this case we will get a notification and be able to answer timely.

    Well, it retrieves children recursively. But only those that are loaded. If you don't expand a node, it means that its children are not loaded into a browser and nothing to send back to server.

    Please try to expand a child node and you'll see that it is being submitted to server.

    So, I think your approach to get children (those that are not loaded to browser) on server is the only solution.
  8. #8
    Thanks Daniil .
  9. #9
    Here is a related thread about a TreePanel's "text" cells not becoming dirty on editing.
    http://forums.ext.net/showthread.php?60341

Similar Threads

  1. Replies: 6
    Last Post: Feb 12, 2015, 10:43 AM
  2. [CLOSED] Sorting Treestore
    By elbanna23 in forum 2.x Legacy Premium Help
    Replies: 4
    Last Post: Nov 20, 2014, 8:53 AM
  3. [CLOSED] how to enumerate treestore?
    By hdsoso in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Jul 31, 2014, 11:30 AM
  4. [CLOSED] TreeStore with IHierarchicalDataSource
    By bbros in forum 2.x Legacy Premium Help
    Replies: 8
    Last Post: Oct 26, 2013, 9:25 AM
  5. [CLOSED] TreeStore issue with 2.2
    By paulc in forum 2.x Legacy Premium Help
    Replies: 3
    Last Post: Aug 19, 2013, 9:24 AM

Tags for this Thread

Posting Permissions