[CLOSED] Ext JS error - Bad Model constructor argument 2 - "session" is not a Session - dragging row onto tree

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] Ext JS error - Bad Model constructor argument 2 - "session" is not a Session - dragging row onto tree

    Hi,

    I am dragging a row from a grid onto a tree node, and I am getting an error.

    First, I've followed your example in the examples explorer
    https://examples3.ext.net/#/DragDrop/Grid/Grid_to_Tree/

    It works without problem. I've tried for a long time to reproduce the error in a cut down sample, but cannot seem to create the right condition.

    However, I can see the code that seems to be the problem, so perhaps there is still a chance you can help.

    When I drop a row onto a tree, I get the following error:

    if (session && !session.isSession) {
        Ext.Error.raise('Bad Model constructor argument 2 - "session" is not a Session');
    }
    This is in the constructor or Ext.data.Model

    This, in turn, is called from the class Ext.tree.ViewDropZone, method handleDropNode, in the local function, transferData:

    for (i = 0 , len = data.records.length; i < len; i++) {
        record = data.records[i];
        if (!record.isNode) {
            if (record.isModel) {
                record = new Model(record.data,record.getId()); // second parameter is invalid! It is not a session!
            } else {
                record = new Model(record);
            }
            data.records[i] = record;
        }
        argList[0] = record;
        insertionMethod.apply(targetNode, argList);
        
        targetView.getNavigationModel().setPosition(record);
    }
    In your example, isModel is false, whereas for me it is true. I cannot see how to influence this and clearly somewhere in my real world code, which is more complex it is being set, but in any simplified version I try to create I just can't seem to get it to be false!

    Because it is true, it creates the new Model. But notice the second parameter to the constructor: record.getId()

    The second parameter to the constructor has to be a session (or null). Because it is a string/id, it eventually results in that error being raised. To me this seems like a Sencha Ext JS bug? But I cannot find anything on their forums about this.

    Questions:

    1. Any idea how isModel is set to true (as I can't create a cut down example to reproduce the problem for you)
    2. Any idea how best to work around this: overriding transferData is not easy because it is a local function inside handleDropNode, which is a large function.
    3. In your example, when the row is added, it is treated like a tree node insertion. In my particular case, I want to invoke an action on the server (which is just a DirectMethod call) but I do NOT want to add the record to the tree (not visibly, anyway). Am I going to find that once the session problem is solved, this is not the right thing I am doing anyway, or this should be okay (I ask because in the debugger when I force the isModel property to false, it ends up creating a tree node to represent the record, which is what I will then need to prevent but I can't easily look into that until the initial session problem is solved first!).


    Sorry I couldn't get a cut down sample to reproduce this... I know that is not ideal at all...

    Thanks.
    Last edited by Daniil; Jan 22, 2015 at 9:13 AM. Reason: [CLOSED]
  2. #2
    Well, as you are on kind of a hard to reproduce case, most that can be done is an exchange of thoughts... Could help, could make things worse...

    Anyway, I've run into a problem somewhat similar to yours where a store was not getting its state 'updating' as true when it was indeed being updated. It happened just on version 3, so, I'd suggest some leads:

    1. If the same functionality is also present on ext.net 2.5, you can give it a try and see if things there works there as expected
    2. In my case, in order to force the updating status to true, instead of whole overriding and event digging, I found that calling a simple store.BeginUpdate() fixed the issue so, maybe there's something that could allow that session variable to get actual session data
    3. See elsewhere (in other controls) how the session is bound and if there's some discrepancies to the code portion you analysed
    4. Sessions are bound to the current user connection. If that session is an Asp.NET session, it would be the case. If by any chance there are async or different threads/tasks in the game, they will most likely get different session IDs or (possibly) no session at all and that would be the problem.
    5. if the problem is just setting the isModel as true it is more likely to have an solution close to (2), by trying to find some equivalent to making an object as that 'model' if in code behind.

    Well, those would be some of the shots I'd give to try and address that issue. Who knows I hit a jackpot there? :) I hope something of that helps.
  3. #3
    Hi

    Thanks for the suggestions. Unfortunately the session is not the ASP.NET session but the Ext JS one used internally to track records. Also the problem is pure client side I think - at least the part to do with drag and drop and where the client side model class is constructed in a way that looks wrong.

    I will keep looking to see where isModel might be set but it may be that is perfectly fine thing for the framework to do and that instead the transfer data function is just incorrect. After all, that function is trying to handle that scenario...
  4. #4
    Ok, so I have dug into this a bit further and found that the isModel is true by default.

    So I think there is a bug in Sencha code in the transferData method I mentioned earlier, where it is passing the record's id as the session argument which doesn't make sense and causes the exception.

    So as I look at why this doesn't happen in the Ext.NET example, I realize that in the example, beforerecorddrop and beforenodedrop methods create their own records and update the data property which is eventually what transferData receives. So these records end up being object hashes, even though this.store.createModel() is called, whereas if you don't do this (which is what I was not doing) you get the actual Store Record being passed through and then that hits the Sencha bug.

    I have not looked at why this bug is not more commonplace. For the moment, I am going to see if I can create my own record (with just an id as that is all I need in this particular case) and see if that will work.
  5. #5
    And now, of course, I can reproduce the problem with this sample:

    <%@ Page Language="C#" %>
     
    <script runat="server">
        private object[] TestData
        {
            get
            {
                DateTime now = DateTime.Now;
     
                return new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, 0.03, now },
                    new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
                    new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
                    new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
                    new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
                    new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
                    new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
                    new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
                    new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
                    new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
                    new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
                    new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
                    new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, now },
                    new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
                    new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
                    new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
                    new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
                    new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
                    new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
                    new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
                    new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
                    new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
                    new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
                    new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
                    new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
                    new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
                    new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
                    new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
                    new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
                };
            }
        }
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.TestData;
                this.Store1.DataBind(); 
            }
        }
    </script>
     
    <!DOCTYPE html>
     
    <html>
    <head runat="server">
        <title>Drag and Drop from GridPanel to TreePanel - Ext.NET Examples</title>
     
        <script>
             var beforerecorddrop = function (node, data, overModel, dropPosition, dropFn) { 
                //if (Ext.isArray(data.records)) {
                //    var records = data.records,
                //        rec;
     
                //    data.records = [];
                    
                //    for (var i = 0; i < records.length; i++) {
                //        rec = records[i];
                        
                //        data.records.push({
                //            text   : rec.get("company"),
                //            leaf   : true,
                //            price  : rec.get("price"),
                //            change : rec.get("change"),
                //            pctChange : rec.get("pctChange"),                        
                //            qtip   : rec.get("lastChange")
                //        });
     
                //        rec.store.remove(rec);
                //    }
                    
                //    return true;
                //}
            };
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            
            <ext:Panel 
                runat="server"
                Width="700" 
                Height="400"
                Layout="BorderLayout">
                <Items>
                    <ext:GridPanel 
                        runat="server"
                        Region="Center"
                        Title="Grid" 
                        MultiSelect="true"
                        MarginSpec="5 0 5 5">
                        <Store>
                            <ext:Store 
                                ID="Store1" 
                                runat="server">
                                <Model>
                                    <ext:Model runat="server">
                                        <Fields>
                                            <ext:ModelField Name="company" />
                                            <ext:ModelField Name="price" Type="Float" />
                                            <ext:ModelField Name="change" Type="Float" />
                                            <ext:ModelField Name="pctChange" Type="Float" />
                                            <ext:ModelField Name="lastChange" Type="Date"/>
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>                    
                        </Store>
                        <ColumnModel runat="server">
                            <Columns>
                                <ext:Column 
                                    runat="server" 
                                    Text="Company" 
                                    Sortable="true" 
                                    DataIndex="company"
                                    Flex="1" 
                                    />
                                <ext:Column 
                                    runat="server" 
                                    Text="Price" 
                                    Width="75" 
                                    Sortable="true" 
                                    DataIndex="price">
                                    <Renderer Format="UsMoney" />
                                </ext:Column>
                            </Columns>
                        </ColumnModel>                    
                        <View>
                            <ext:GridView runat="server">
                                <Plugins>
                                    <ext:GridDragDrop runat="server" DragGroup="grid2tree" />
                                </Plugins>
                            </ext:GridView>
                        </View>
                    </ext:GridPanel>
                        
                    <ext:TreePanel 
                        runat="server" 
                        Region="East"                    
                        Width="300"
                        Title="Tree"
                        AutoScroll="true"                    
                        MarginSpec="5 5 5 0"
                        Split="true">
                        <Root>
                            <ext:Node Text="Root" Expanded="true" AllowDrag="false">                        
                                <Children>
                                    <ext:Node Text="Folder 1" Qtip="Rows dropped here will be appended to the folder" AllowDrag="false">
                                        <Children>
                                            <ext:Node Text="Subleaf 1" Qtip="Subleaf 1 Quick Tip" Leaf="true"  AllowDrag="false"/>
                                        </Children>
                                    </ext:Node>
                                            
                                    <ext:Node Text="Folder 2" Qtip="Rows dropped here will be appended to the folder" AllowDrag="false">
                                        <Children>
                                            <ext:Node Text="Subleaf 2" Qtip="Subleaf 2 Quick Tip" Leaf="true"  AllowDrag="false"/>
                                        </Children>
                                    </ext:Node>
                                            
                                    <ext:Node Text="Leaf 1" Qtip="Leaf 1 Quick Tip" Leaf="true" AllowDrag="false" />
                                </Children>
                            </ext:Node>
                        </Root>
                        <View>
                            <ext:TreeView runat="server">
                                <Plugins>
                                    <ext:TreeViewDragDrop runat="server" DropGroup="grid2tree" />
                                </Plugins>
                                <Listeners>
                                    <BeforeDrop Fn="beforerecorddrop" />
                                </Listeners>
                            </ext:TreeView>
                        </View>              
                    </ext:TreePanel>
                </Items>
            </ext:Panel> 
        </form>
    </body>
    </html>
    Notice that the JavaScript event handler code is commented out. When commented out you will get the error I noted initially. When uncommented, things work.

    Question is why was this JavaScript code needed? Was it to workaround this very specific issue? I don't see any documentation on the Sencha docs about needing to change the records from the one you get by default, in this way... And I am surprised therefore this is not raised more often on the Sencha forums (in fact, it is only raised once in a tree node to tree node drag operation, which has a solution that cannot apply here to grids).
  6. #6
    I think I finally figured it out now.

    I got too hung up on that error (which I think is still an issue and may raise with Sencha at some point).

    But what I ultimately wanted was:
    - Drag row(s) onto a tree node
    - Prevent tree nodes from being dragged to tree
    - Get those row ids and call some AJAX/DirectMethod to process those
    - NOT remove the records from the grid (by default the records are removed)

    To prevent removing records from the grid when they have been dropped, the trick was to empty out the records passed into the beforedrop method.

    Thanks to this forum post at Sencha for the tips:
    http://www.sencha.com/forum/showthre...ng-a-tree-node

    So a final working solution:

    <%@ Page Language="C#" %>
     
    <script runat="server">
        private object[] TestData
        {
            get
            {
                DateTime now = DateTime.Now;
     
                return new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, 0.03, now },
                    new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
                    new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
                    new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
                    new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
                    new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
                    new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
                    new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
                    new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
                    new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
                    new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
                    new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
                    new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, now },
                    new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
                    new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
                    new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
                    new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
                    new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
                    new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
                    new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
                    new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
                    new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
                    new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
                    new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
                    new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
                    new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
                    new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
                    new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
                    new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
                };
            }
        }
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.TestData;
                this.Store1.DataBind(); 
            }
        }
    </script>
     
    <!DOCTYPE html>
     
    <html>
    <head runat="server">
        <title>Drag and Drop from GridPanel to TreePanel - Ext.NET Examples</title>
     
        <script>
            var beforedrop = function(node, data, overModel, dropPos, opts) {
                this.droppedRecords = data.records;
                data.records = [];
            };
     
            var drop = function(node, data, overModel, dropPos, opts) {
                var str = '';
     
                Ext.iterate(this.droppedRecords, function (record) {
                    str += record.get('title') + ' (id = ' + record.get('id') + ') dropped on ' + overModel.get('text') + '\n';
                });
                console.log(str);
                        
                delete this.droppedRecords;
            }
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            
            <ext:Panel 
                runat="server"
                Width="700" 
                Height="400"
                Layout="BorderLayout">
                <Items>
                    <ext:GridPanel 
                        runat="server"
                        Region="Center"
                        Title="Grid" 
                        MultiSelect="true"
                        MarginSpec="5 0 5 5">
                        <Store>
                            <ext:Store 
                                ID="Store1" 
                                runat="server">
                                <Model>
                                    <ext:Model runat="server">
                                        <Fields>
                                            <ext:ModelField Name="company" />
                                            <ext:ModelField Name="price" Type="Float" />
                                            <ext:ModelField Name="change" Type="Float" />
                                            <ext:ModelField Name="pctChange" Type="Float" />
                                            <ext:ModelField Name="lastChange" Type="Date"/>
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>                    
                        </Store>
                        <ColumnModel runat="server">
                            <Columns>
                                <ext:Column 
                                    runat="server" 
                                    Text="Company" 
                                    Sortable="true" 
                                    DataIndex="company"
                                    Flex="1" 
                                    />
                                <ext:Column 
                                    runat="server" 
                                    Text="Price" 
                                    Width="75" 
                                    Sortable="true" 
                                    DataIndex="price">
                                    <Renderer Format="UsMoney" />
                                </ext:Column>
                            </Columns>
                        </ColumnModel>                    
                        <View>
                            <ext:GridView runat="server">
                                <Plugins>
                                    <ext:GridDragDrop runat="server" DragGroup="grid2tree" />
                                </Plugins>
                            </ext:GridView>
                        </View>
                    </ext:GridPanel>
                        
                    <ext:TreePanel 
                        runat="server" 
                        Region="East"                    
                        Width="300"
                        Title="Tree"
                        AutoScroll="true"                    
                        MarginSpec="5 5 5 0"
                        Split="true">
                        <Root>
                            <ext:Node Text="Root" Expanded="true">                        
                                <Children>
                                    <ext:Node Text="Folder 1">
                                        <Children>
                                            <ext:Node Text="Subleaf 1" Qtip="Subleaf 1 Quick Tip" Leaf="true" />
                                        </Children>
                                    </ext:Node>
                                            
                                    <ext:Node Text="Folder 2">
                                        <Children>
                                            <ext:Node Text="Subleaf 2" Leaf="true" />
                                        </Children>
                                    </ext:Node>
                                            
                                    <ext:Node Text="Leaf 1" Leaf="true" />
                                </Children>
                            </ext:Node>
                        </Root>
                        <View>
                            <ext:TreeView runat="server">
                                <Plugins>
                                    <ext:TreeViewDragDrop runat="server" DropGroup="grid2tree" EnableDrag="false" />
                                </Plugins>
                                <Listeners>
                                    <BeforeDrop Fn="beforedrop" />
                                    <Drop Fn="drop" />
                                </Listeners>
                            </ext:TreeView>
                        </View>              
                    </ext:TreePanel>
                </Items>
            </ext:Panel> 
        </form>
    </body>
    </html>
    In the above example, I am writing out some basic info to the browser console (as per the example from the Sencha forums). It is here where the data can be passed to the server via ajax if needed.

    Hope that helps someone!

    (Daniil, I think this can be marked as closed, or maybe moved to the Examples and Extras?)
  7. #7
    Anup, it looks to me like that javascript is needed to convert an item from one kind to another, like a data type mapping. You're moving something from a grid to a treegrid, isn't it? Drag+drop might encapsulate whatever you're dragging so it needs to be mapped back wherever you drop it. That really seems to be the cause. This way we could think, for example, on dragging something from inside a grid inside a window to a treeGrid somewhere else. Possibly even another page!

    By the way, you're quite the self-sufficient one, aren't you! :)

    Sometime back last year I was like this with a thread; posting my questions -and- solutions. Sometimes writing the question gives us answers or insights for the problem itself. :)
  8. #8
    Yes, that is right - a data mapping from grid record to tree record - I think I was looking at this too long to see that! Even when I solved it I missed that was the issue until you put it that way! Thanks for that.

    Yes, writing it down helps clarify and often I start drafting a post only to find I have the solution. This time I just went down the wrong path and didn't think clearly!

    Thanks!
  9. #9
    Anup, before I move it to the Examples and Extras forum, what Title would you like to see?
  10. #10
    Ah, yes, thanks for reminding me. I was going to suggest a title but forgot to do so!

    Maybe something like

    How to drag a grid row onto a tree without moving the record into the tree

    ?

    Also, because there is a lot of "noise" in the thread about my side track into what caused the error, might it be easier for people if I just duplicate my final post that has the working solution as a separate post in the Examples and Extras with the new title, instead of moving this thread?
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] The function "addScript" causing the error "Syntax Error"
    By Woyciniuk in forum 3.x Legacy Premium Help
    Replies: 22
    Last Post: Sep 26, 2015, 8:56 AM
  2. Replies: 1
    Last Post: Oct 05, 2012, 11:56 AM
  3. [CLOSED] IE8 combo "Invalid argument" on z-index
    By ljcorreia in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Feb 22, 2011, 10:10 AM
  4. Adding a tree node using "Mode=Remote"
    By mattwoberts in forum 1.x Help
    Replies: 2
    Last Post: Jan 07, 2011, 3:10 PM
  5. Replies: 16
    Last Post: Oct 15, 2010, 10:04 AM

Posting Permissions