[CLOSED] DataView Drag & Drop

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] DataView Drag & Drop

    Hi,

    I need something like a grid with N columns and N rows, each cell must be drag&drop to another cell of this grid.
    Each cell contain three lines of information an a image, that will be editable in a modal window when each item is clicked.
    I thought in use a dataview, but I see this thread http://forums.ext.net/showthread.php...ng-in-Dataview

    Is there any automated way to perform this, or I must to implement it like you mention in the thread?

    Also, use a dataview it's not priority only an idea. Is there a simple way with a grid or another control?

    Any help or idea would be appreciated.

    Thanks
    Last edited by Daniil; Apr 16, 2013 at 5:38 AM. Reason: [CLOSED]
  2. #2
    Hi @softmachine2011,

    There is the CellDragDrop plugin for a GridView.
    http://docs.sencha.com/ext-js/4-2/#!...x.CellDragDrop

    Example
    <%@ Page Language="C#" %>
     
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[] 
                { 
                    new object[] { "test1", "test2", "test3" },
                    new object[] { "test4", "test5", "test6" },
                    new object[] { "test7", "test8", "test9" }
                };
                store.DataBind();
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Ext.NET v2 Example</title>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            <ext:GridPanel ID="GridPanel1" runat="server">
                <Store>
                    <ext:Store runat="server">
                        <Model>
                            <ext:Model runat="server">
                                <Fields>
                                    <ext:ModelField Name="test1" />
                                    <ext:ModelField Name="test2" />
                                    <ext:ModelField Name="test3" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:Column runat="server" Text="Test1" DataIndex="test1" />
                        <ext:Column runat="server" Text="Test2" DataIndex="test2" />
                        <ext:Column runat="server" Text="Test3" DataIndex="test3" />
                    </Columns>
                </ColumnModel>
                <View>
                    <ext:GridView runat="server">
                        <Plugins>
                            <ext:CellDragDrop runat="server" />
                        </Plugins>
                    </ext:GridView>
                </View>
            </ext:GridPanel>
        </form>
    </body>
    </html>
    Regarding a DataView. There is no built-in drag&drop. It will require implementing.

    Regarding editing. I think it should be possible to implement with either a GridPanel or a DataView.

    Hope this helps.
  3. #3
    Well, this plugin exists in ExtJS 4.2 -> Ext.NET 2.2...

    As I can see, in ExtJS 4.1.3 -> Ext.NET 2.1, doesn't exists, is there a way to avoid upgrade to Ext.NET 2.2 that doesn't involve to implement it at all manually?

    Thanks.
  4. #4
    I would try to copy the plugin's sources and use it via JavaScript and/or a GenericPlugin.
  5. #5
    Ok thanks, I've been expecting your results and conclusions
  6. #6
    Well, I said what I would do if I were you:)

    I will rephrase. You can try to copy the plugin's sources and use it via JavaScript and/or a GenericPlugin.

    Please clarify do you need any assistance on this?
  7. #7
    It seems that there are some new stuff in Ext4.2 that Ext4.1.3 doesn't have, obviously:

    Exactly in line 163 of source code
    getDragData: function (e) {
                        var view = this.view,
                            item = e.getTarget(view.getItemSelector()),
                            record = view.getRecord(item),
                            clickedEl = e.getTarget(view.getCellSelector()),
                            dragEl;
    Function getCellSelector doesn't exists

    Well it seems that there is no quickly solution, and I must have to implement a custom plugin or something else, is it or have anymore idea?
  8. #8
    It seems the single thing you should add to get the plugin working.
    http://docs.sencha.com/ext-js/4-2/so...etCellSelector

    getCellSelector
    Ext.view.Table.override({
        getCellSelector: function(header) {
            var result = this.cellSelector;
            if (header) {
                result += '-' + header.getItemId();
            }
            return result;
        }    
    });
    Example
    <%@ Page Language="C#" %>
     
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[] 
                { 
                    new object[] { "test1", "test2", "test3" },
                    new object[] { "test4", "test5", "test6" },
                    new object[] { "test7", "test8", "test9" }
                };
                store.DataBind();
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Ext.NET v2 Example</title>
    
        <script src="resources/js/CellDragDrop.js"></script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            <ext:GridPanel ID="GridPanel1" runat="server">
                <Store>
                    <ext:Store runat="server">
                        <Model>
                            <ext:Model runat="server">
                                <Fields>
                                    <ext:ModelField Name="test1" />
                                    <ext:ModelField Name="test2" />
                                    <ext:ModelField Name="test3" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:Column runat="server" Text="Test1" DataIndex="test1" />
                        <ext:Column runat="server" Text="Test2" DataIndex="test2" />
                        <ext:Column runat="server" Text="Test3" DataIndex="test3" />
                    </Columns>
                </ColumnModel>
                <View>
                    <ext:GridView runat="server">
                        <Plugins>
                            <ext:GenericPlugin runat="server" InstanceName="Ext.ux.CellDragDrop" />
                        </Plugins>
                    </ext:GridView>
                </View>
            </ext:GridPanel>
        </form>
    </body>
    </html>
    CellDragDrop.js
    Ext.view.Table.override({
        getCellSelector: function(header) {
            var result = this.cellSelector;
            if (header) {
                result += '-' + header.getItemId();
            }
            return result;
        }    
    });
    
    
    /**
     * This plugin can enable a cell to cell drag and drop operation within the same grid view.
     *
     * Note that the plugin must be added to the grid view, not to the grid panel. For example, using {@link Ext.panel.Table viewConfig}:
     *
     *      viewConfig: {
     *          plugins: {
     *              ptype: 'celldragdrop',
     *
     *              // Remove text from source cell and replace with value of emptyText.
     *              applyEmptyText: true,
     *
     *              //emptyText: Ext.String.htmlEncode('<<foo>>'),
     *
     *              // Will only allow drops of the same type.
     *              enforceType: true
     *          }
     *      }
     */
    Ext.define('Ext.ux.CellDragDrop', {
        extend: 'Ext.AbstractPlugin',
        alias: 'plugin.celldragdrop',
    
        uses: ['Ext.view.DragZone'],
    
        /**
         * @cfg {Boolean} enforceType
         * Set to `true` to only allow drops of the same type.
         *
         * Defaults to `false`.
         */
        enforceType: false,
    
        /**
         * @cfg {Boolean} applyEmptyText
         * If `true`, then use the value of {@link #emptyText} to replace the drag record's value after a node drop.
         * Note that, if dropped on a cell of a different type, it will convert the default text according to its own conversion rules.
         *
         * Defaults to `false`.
         */
        applyEmptyText: false,
    
        /**
         * @cfg {Boolean} emptyText
         * If {@link #applyEmptyText} is `true`, then this value as the drag record's value after a node drop.
         *
         * Defaults to an empty string.
         */
        emptyText: '',
    
        /**
         * @cfg {Boolean} dropBackgroundColor
         * The default background color for when a drop is allowed.
         *
         * Defaults to green.
         */
        dropBackgroundColor: 'green',
    
        /**
         * @cfg {Boolean} noDropBackgroundColor
         * The default background color for when a drop is not allowed.
         *
         * Defaults to red.
         */
        noDropBackgroundColor: 'red',
    
        //<locale>
        /**
         * @cfg {String} dragText
         * The text to show while dragging.
         *
         * Two placeholders can be used in the text:
         *
         * - `{0}` The number of selected items.
         * - `{1}` 's' when more than 1 items (only useful for English).
         */
        dragText: '{0} selected row{1}',
        //</locale>
    
        /**
         * @cfg {String} ddGroup
         * A named drag drop group to which this object belongs. If a group is specified, then both the DragZones and
         * DropZone used by this plugin will only interact with other drag drop objects in the same group.
         */
        ddGroup: "GridDD",
    
        /**
         * @cfg {Boolean} enableDrop
         * Set to `false` to disallow the View from accepting drop gestures.
         */
        enableDrop: true,
    
        /**
         * @cfg {Boolean} enableDrag
         * Set to `false` to disallow dragging items from the View.
         */
        enableDrag: true,
    
        /**
         * @cfg {Object/Boolean} containerScroll
         * True to register this container with the Scrollmanager for auto scrolling during drag operations.
         * A {@link Ext.dd.ScrollManager} configuration may also be passed.
         */
        containerScroll: false,
    
        init: function (view) {
            var me = this;
    
            view.on('render', me.onViewRender, me, {
                single: true
            });
        },
    
        destroy: function () {
            var me = this;
    
            Ext.destroy(me.dragZone, me.dropZone);
        },
    
        enable: function () {
            var me = this;
    
            if (me.dragZone) {
                me.dragZone.unlock();
            }
            if (me.dropZone) {
                me.dropZone.unlock();
            }
            me.callParent();
        },
    
        disable: function () {
            var me = this;
    
            if (me.dragZone) {
                me.dragZone.lock();
            }
            if (me.dropZone) {
                me.dropZone.lock();
            }
            me.callParent();
        },
    
        onViewRender: function (view) {
            var me = this,
                scrollEl;
    
            if (me.enableDrag) {
                if (me.containerScroll) {
                    scrollEl = view.getEl();
                }
    
                me.dragZone = new Ext.view.DragZone({
                    view: view,
                    ddGroup: me.dragGroup || me.ddGroup,
                    dragText: me.dragText,
                    containerScroll: me.containerScroll,
                    scrollEl: scrollEl,
                    getDragData: function (e) {
                        var view = this.view,
                            item = e.getTarget(view.getItemSelector()),
                            record = view.getRecord(item),
                            clickedEl = e.getTarget(view.getCellSelector()),
                            dragEl;
    
                        if (item) {
                            dragEl = document.createElement('div');
                            dragEl.className = 'x-form-text';
                            dragEl.appendChild(document.createTextNode(clickedEl.textContent || clickedEl.innerText));
    
                            return {
                                event: new Ext.EventObjectImpl(e),
                                ddel: dragEl,
                                item: e.target,
                                columnName: view.getGridColumns()[clickedEl.cellIndex].dataIndex,
                                record: record
                            };
                        }
                    },
    
                    onInitDrag: function (x, y) {
                        var self = this,
                            data = self.dragData,
                            view = self.view,
                            selectionModel = view.getSelectionModel(),
                            record = data.record,
                            el = data.ddel;
    
                        // Update the selection to match what would have been selected if the user had
                        // done a full click on the target node rather than starting a drag from it.
                        if (!selectionModel.isSelected(record)) {
                            selectionModel.select(record, true);
                        }
    
                        self.ddel.update(el.textContent || el.innerText);
                        self.proxy.update(self.ddel.dom);
                        self.onStartDrag(x, y);
                        return true;
                    }
                });
            }
    
            if (me.enableDrop) {
                me.dropZone = new Ext.dd.DropZone(view.el, {
                    view: view,
                    ddGroup: me.dropGroup || me.ddGroup,
                    containerScroll: true,
    
                    getTargetFromEvent: function (e) {
                        var self = this,
                            v = self.view,
                            cell = e.getTarget(v.cellSelector),
                            row, columnIndex;
    
                        // Ascertain whether the mousemove is within a grid cell.
                        if (cell) {
                            row = v.findItemByChild(cell);
                            columnIndex = cell.cellIndex;
    
                            if (row && Ext.isDefined(columnIndex)) {
                                return {
                                    node: cell,
                                    record: v.getRecord(row),
                                    columnName: self.view.up('grid').columns[columnIndex].dataIndex
                                };
                            }
                        }
                    },
    
                    // On Node enter, see if it is valid for us to drop the field on that type of column.
                    onNodeEnter: function (target, dd, e, dragData) {
                        var self = this,
                            destType = target.record.fields.get(target.columnName).type.type.toUpperCase(),
                            sourceType = dragData.record.fields.get(dragData.columnName).type.type.toUpperCase();
    
                        delete self.dropOK;
    
                        // Return if no target node or if over the same cell as the source of the drag.
                        if (!target || target.node === dragData.item.parentNode) {
                            return;
                        }
    
                        // Check whether the data type of the column being dropped on accepts the
                        // dragged field type. If so, set dropOK flag, and highlight the target node.
                        if (me.enforceType && destType !== sourceType) {
    
                            self.dropOK = false;
    
                            if (me.noDropCls) {
                                Ext.fly(target.node).addCls(me.noDropCls);
                            } else {
                                Ext.fly(target.node).applyStyles({
                                    backgroundColor: me.noDropBackgroundColor
                                });
                            }
    
                            return;
                        }
    
                        self.dropOK = true;
    
                        if (me.dropCls) {
                            Ext.fly(target.node).addCls(me.dropCls);
                        } else {
                            Ext.fly(target.node).applyStyles({
                                backgroundColor: me.dropBackgroundColor
                            });
                        }
                    },
    
                    // Return the class name to add to the drag proxy. This provides a visual indication
                    // of drop allowed or not allowed.
                    onNodeOver: function (target, dd, e, dragData) {
                        return this.dropOK ? this.dropAllowed : this.dropNotAllowed;
                    },
    
                    // Highlight the target node.
                    onNodeOut: function (target, dd, e, dragData) {
                        var cls = this.dropOK ? me.dropCls : me.noDropCls;
    
                        if (cls) {
                            Ext.fly(target.node).removeCls(cls);
                        } else {
                            Ext.fly(target.node).applyStyles({
                                backgroundColor: ''
                            });
                        }
                    },
    
                    // Process the drop event if we have previously ascertained that a drop is OK.
                    onNodeDrop: function (target, dd, e, dragData) {
                        if (this.dropOK) {
                            target.record.set(target.columnName, dragData.record.get(dragData.columnName));
                            if (me.applyEmptyText) {
                                dragData.record.set(dragData.columnName, me.emptyText);
                            }
                            return true;
                        }
                    },
    
                    onCellDrop: Ext.emptyFn
                });
            }
        }
    });
    Last edited by Daniil; Apr 11, 2013 at 4:41 PM.
  9. #9
    Yes, it seems that it accomplish drag and drop as well.

    I expected that if I drag a cell to another cell, it swaps both cells. For it I changed onNodeDrop function with this:
    onNodeDrop: function (target, dd, e, dragData) {
                        if (this.dropOK) {
                            var dropRecordClone = target.record.copy();
                            
                            target.record.set(target.columnName, dragData.record.get(dragData.columnName));
                            dragData.record.set(dragData.columnName, dropRecordClone.get(target.columnName));
                            
                            return true;
                        }
                    }
    Because I see that onCellDrop is not fired anywhere...

    Is it correct or you would change something?

    Thanks for your effort.
  10. #10
    Your change looks correct.
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] DataView to DataView Drag and Drop
    By paulc in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: May 10, 2012, 8:19 PM
  2. Drag and drop reordering in Dataview
    By jophinm in forum 1.x Help
    Replies: 2
    Last Post: Nov 11, 2011, 11:19 AM
  3. [CLOSED] Drag-Drop From DataView to TreePanel
    By juanpablo.belli@huddle.com.ar in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Feb 11, 2009, 6:46 AM
  4. [CLOSED] MultiSelect with drag and drop, Drop listener
    By Jurke in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Jan 30, 2009, 8:25 AM

Tags for this Thread

Posting Permissions