[CLOSED] Drag and Drop from grid to grid - cancel data transfer operation

  1. #1

    [CLOSED] Drag and Drop from grid to grid - cancel data transfer operation

    Hello support team,
    I have bidirectional dragging from one grid to another. The first grid contains all the companies, the second one only favourites. Since for favourites we need only to show the Name, the model is different on both grids:

    @using Ext.Net;
    @using Ext.Net.MVC;
    
    @{
        ViewBag.Title = "Grid Drag & Drop";
        Layout = null;
    
        var X = Html.X();
    
        var ModelC = new object[]
            {
                        new object[] { "3m Co", "9/1 12:00am" },
                        new object[] { "Alcoa Inc", "9/1 12:00am" },
                        new object[] { "Altria Group Inc", "9/1 12:00am" },
                        new object[] { "American Express Company", "9/1 12:00am" },
                        new object[] { "AT&T Inc.", "9/1 12:00am" },
                        new object[] { "Boeing Co.", "9/1 12:00am" },
                        new object[] { "Wal-Mart Stores, Inc.", "9/1 12:00am" }
            };
    
        var ModelF = new object[]
            {
                        new object[] { "3m Co" },
                        new object[] { "Boeing Co." },
            };
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Ext.NET MVC Test Case</title>
    </head>
    
    <body>
        @(X.ResourceManager())
    
        @X.DisplayField().ID("version").ReadOnly(true).Margin(10).Width(200)
    
        @(X.Panel().Width(500).Height(300)
            .LayoutConfig(new HBoxLayoutConfig { Align = HBoxAlign.Stretch })
            .Items(
                X.GridPanel().ItemID("grdCompanies").Flex(2)
                    .Title("All Companies")
                    .Padding(5)
                    .Store(Html.X().Store()
                        .Model(Html.X().Model()
                            .Fields(
                                new ModelField("company"),
                                new ModelField("lastChange", ModelFieldType.Date, "M/d hh:mmtt")
                            )
                        )
                        .DataSource(ModelC)
                    )
                    .ColumnModel(
                        Html.X().Column().Text("Company").DataIndex("company").Flex(1),
                        Html.X().DateColumn().Text("Last Updated").DataIndex("lastChange").Width(90)
                    )
                    .View(
                        X.GridView()
                            .Plugins(X.GridDragDrop().DragGroup("ddGroupAllCompanies").DropGroup("ddGroupFavourites").Copy(true))
                            .Listeners(l =>
                            {
                                l.BeforeDrop.Handler = "console.log('BEFORE_DROP', data.records[0].id); return 0;";
                            })
                    ),
                X.GridPanel().ItemID("grdFavourites").Flex(1)
                    .Title("Favourites")
                    .Padding(5)
                    .Store(Html.X().Store()
                        .Model(Html.X().Model()
                            .Fields(
                                new ModelField("company")
                            )
                        )
                        .DataSource(ModelF)
                    )
                    .ColumnModel(
                        Html.X().Column().Text("Company").DataIndex("company").Flex(1)
                    )
                    .View(
                        X.GridView()
                            .Plugins(X.GridDragDrop().DragGroup("ddGroupFavourites").DropGroup("ddGroupAllCompanies"))
                            .Listeners(l =>
                            {
                                l.BeforeDrop.Handler = "console.log('BEFORE_DROP', data.records[0].id)";
                            })
                    )
            )
        )
    
    </body>
    </html>
    
    <script type="text/javascript">
        Ext.onReady(function () {
            Ext.getCmp("version").setValue("Ext JS " + Ext.getVersion().version + " / " + "Ext.NET " + Ext.net.Version);
        });
    </script>
    What I want to achieve is this:

    1. Drag and drop from companies to favourites: keep a record in company list and insert it into favourites - this can be done with the Copy(true) setting on the first grid.

    2. Drag and drop from favourites to companies: remove a record from favourites, but do not insert in the company list (cancel data transfer operation when dropped) - according to the documentation, this should be achieved by returning 0 from the BeforeDrop event handler:

    Returning 0 signals that the data transfer operation should not take place, but that the gesture was valid, and that the repair operation should not take place.

    But that doesn't seem to work. Point 1 scenario works well, but moving records back causes two situations on company grid:

    A. If the record is dragged from companies to favourites and immediately back to companies, the record is not inserted because it keeps the same id and the record is only placed at the drop position.

    B. If a preloaded favourite is moved to companies, it is inserted a second time because id does not match the record id of the related company.

    Did I misunderstand how the BeforeDrop event works or is it a bug? How to achieve the behavior described above?

    Thank you for your help.

    Ext JS 6.5.1.345 / Ext.NET 4.4.1

    Kind regards
    Dan
    Last edited by fabricio.murta; May 17, 2019 at 5:30 PM.
  2. #2
    Hello Dan!

    I see you found this from Ext.NET documentation:

    Quote Originally Posted by NewLink
    according to the documentation, this should be achieved by returning 0 from the BeforeDrop event handler:

    Returning 0 signals that the data transfer operation should not take place, but that the gesture was valid, and that the repair operation should not take place.

    But that doesn't seem to work.
    Which would be coming from the Ext.Net.TableViewListeners.BeforeDrop part of the docs/intellisense.

    According to the respective Sencha documentation on the event, it is no longer actual, and there's not even any mention to what should happen if 0 is returned. Just false, which effectively cancels the drop operation completely.

    I am afraid the only solution available would be to manipulate/replace the dropFunction.process() method during the event. This is also out of sync with Sencha documentation, which points it as dropHandler. The former is valid in Ext.NET context still and should work. I will see if I can suggest you a simple change in this handler to attain your objective and get back to you shortly.
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Hello again, Dan!

    The only way I could find was to actually override the default behavior (avoiding an extension), so that you get the specific behavior of not adding the moved item to wherever it is dropped. But this won't count if you drag-drop to another drop zone (if that's not another grid view plugin).

    So, for instance, you'd need further overrides if you have other drop zones (mostly from other components' plug ins) accepting drags from the favorites to remove it (e.g. if you wanted to allow favorites being removed just by dragging anywhere in the screen). But you wouldn't need to worry much about that if you added a drop zone the whole remaining page -- as in that case you're responsible for writing the drop handler logic anyway.

    Ext.define("custom_drop_handler", {
        override: "Ext.grid.ViewDropZone",
        handleNodeDrop: function (data, record, position) {
            var view = this.view,
                store = view.getStore(),
                crossView = view !== data.view,
                selectAfter = crossView || data.records.length > 1,
                index, records, i, len;
    
            if (data.copy) {
                records = data.records;
                for (i = 0, len = records.length; i < len; i++) {
                    records[i] = records[i].copy();
                }
            } else if (selectAfter) {
    
                data.view.store.remove(data.records);
            }
    
            // We'll only ever add entries to the target if the source was
            // not our favourites grid.
            if (data.view.ownerGrid.itemId != "grdFavourites") {
                if (record && position) {
                    index = store.indexOf(record);
    
                    if (position !== 'before') {
                        index++;
                    }
    
                    store.insert(index, data.records);
                } else {
                    store.add(data.records);
                }
            }
    
            if (selectAfter) {
                view.getSelectionModel().select(data.records);
            }
    
            view.getNavigationModel().setPosition(data.records[0]);
        }
    });
    The change to the original method is on line 22, so that whenever the source grid is the favorites one, it would inhibit the target's add method.

    Well, hope this helps!
    Fabrício Murta
    Developer & Support Expert
  4. #4
    Hello Fabrício,
    thank you for outlining a possible solution. It is quite hardcoded, but sometimes the simple solutions are the best. It works well for my purpose and issue can be closed.

    Thank you for highly helpful assistance.

    Kind regards
    Dan
  5. #5
    Hello Dan!

    Glad it helped, and thank you very much for your kind feedback!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. [CLOSED] Drag drop (grid to grid) store.sync() problem
    By siyahgul in forum 2.x Premium Help
    Replies: 3
    Last Post: Feb 17, 2015, 11:58 AM
  2. Replies: 13
    Last Post: Sep 26, 2013, 10:04 AM
  3. Replies: 4
    Last Post: Jul 19, 2013, 1:16 AM
  4. Replies: 0
    Last Post: Apr 02, 2013, 5:25 AM
  5. Replies: 0
    Last Post: Nov 20, 2009, 3:24 AM

Tags for this Thread

Posting Permissions