[OPEN] [#933] [3.2.1] Drag/Drop Issues DropTarget and touchscreen

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    [OPEN] [#933] [3.2.1] Drag/Drop Issues DropTarget and touchscreen

    I opened a new thread as this is a super critical defect for us and it slightly different than all the other ones i opened on drag/drop. Took us a long time to figure out the problem.

    Issue: On a touch enabled laptop, drag and drop is broken in our grids. In a non-touch enabled laptop, it works fine.

    Cause: the problem is that the touch enabled laptops dont register the mouse click/press event to initiate the drag. it only works on LongPress. Problem is that 99% of our users have a 24 inch monitor hooked to their laptop and dont even use the touchscreen. But by having a touchscreen, it causes the drag to require a LongPress.

    Resolution: it should work on Click OR LongPress if the screen is touch enabled. It should not be either or.

    The example below highlights the bug easily. i tested (code below) on the client machine and it works only with LongPress. I tested it in Chrome (and set device to laptop with touch) and it was able to replicate the problem also.

    Customer also opened his laptop and tested on his real touch screen and the longpress worked fine.

    Thanks
    /Z



    <%@ Page Language="C#" %>
    
    
    <%@ Import Namespace="System.Collections.Generic" %>
    
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
         {
             this.Store1.DataSource = new List<Project> 
             { 
                new Project(100, "Ext Forms: Field Anchoring1", 1, "Integrate 2.0 Forms with 2.0 Layouts", 6, 150, 0, new DateTime(2007, 06, 24)),
                new Project(100, "Ext Forms: Field Anchoring2", 2, "Implement AnchorLayout", 4, 150, 0, new DateTime(2007, 06, 25)),
                new Project(200, "Ext Forms: Field Anchoring3", 3, "Add support for multiple types of anchors", 4, 150, 0, new DateTime(2007, 06, 27)),
                new Project(200, "Ext Forms: Field Anchoring4", 4, "Testing and debugging", 8, 0, 0, new DateTime(2007, 06, 29)),
                new Project(300, "Ext Forms: Field Anchoring5", 5, "Integrate 2.0 Forms with 2.0 Layouts", 6, 150, 0, new DateTime(2007, 06, 24)),
                new Project(300, "Ext Forms: Field Anchoring6", 6, "Implement AnchorLayout", 4, 150, 0, new DateTime(2007, 06, 25)),
                new Project(400, "Ext Forms: Field Anchoring7", 7, "Add support for multiple types of anchors", 4, 150, 0, new DateTime(2007, 06, 27)),
                new Project(400, "Ext Forms: Field Anchoring8", 8, "Add support for multiple types of anchors", 4, 150, 0, new DateTime(2007, 06, 27)),
             };
    
    
            this.Store1.DataBind();
        }
    
    
        public class Project
        {
            public Project(int projectId, string name, int taskId, string description, int estimate, double rate, double cost, DateTime due)
            {
                this.ProjectID = projectId;
                this.Name = name;
                this.TaskID = taskId;
                this.Description = description;
                this.Estimate = estimate;
                this.Rate = rate;
                this.Due = due;
            }
    
    
            public int ProjectID { get; set; }
            public string Name { get;set; }
            public int TaskID { get; set; }
            public string Description { get;set; }
            public int Estimate { get;set; }
            public double Rate { get; set; }
            public double Cost { get; set; }
            public DateTime Due { get; set; }
        }
    </script>
    
    
    <!DOCTYPE html>
    
    
    <html>
    <head id="Head1" runat="server">
        <title>D&D bug</title>
        
        <script type="text/javascript">
            var lastClickedColumn = false;
            var lastClickedRow = false;
    
    
            var saveMouseDown = function (grid, record, item, index, e, eOpts) {
                if (e.button == 0) {    //left button
                    lastClickedRow = e.position.rowIdx;
                    lastClickedColumn = e.position.column.fullColumnIndex;
                }
            };
    
    
            var onAfterRenderDragAndDrop = function (view) {
                var cellDragDrop;
    
    
                Ext.Array.each(view.getPlugins()[0], function (plugin) {
                    if (plugin instanceof Ext.ux.CellDragDrop) {
                        cellDragDrop = plugin;
                        return false;
                    }
                });
    
    
                if (cellDragDrop.dragZone) {
                    cellDragDrop.dragZone.onBeforeDrag = function (data, e) {
                        if (!data.columnName) { // It means no DataIndex
                            return false;
                        }
                    }
                }
            };
    
    
            var notifyOver2 = function (ddSource, e, data) {
                var targetRecordData = (ddSource.view.getRecord(ddSource.view.findItemByChild(e.target)).data);
                var sourceRecordData = ddSource.view.getStore().getAt(lastClickedRow).data;
    
    
                if (sourceRecordData.ProjectID == targetRecordData.ProjectID) {
                    return this.dropAllowed;
                }
    
    
                return this.dropNotAllowed;
            };
    
    
            var notifyDrop2 = function (ddSource, e, data) {
                ddSource.view.getStore().suspendEvents(true);
    
    
                var targetRecord = ddSource.view.getRecord(ddSource.view.findItemByChild(e.target));
                var sourceRecord = ddSource.view.getStore().getAt(lastClickedRow);
    
    
                var targetRecordData = targetRecord.data;
                var sourceRecordData = sourceRecord.data;
                
                if (!(sourceRecordData.ProjectID == targetRecordData.ProjectID)) {
                    ddSource.view.getStore().resumeEvents();
                    return false;
                }
    
    
                var sourceColumn = ddSource.view.grid.columns[lastClickedColumn];
                var targetColumn = ddSource.view.getHeaderByCell(Ext.fly(e.target).findParent(ddSource.view.cellSelector));
                if (sourceColumn == null || targetColumn == null) {
                    ddSource.view.getStore().resumeEvents();
                    return false;
                }
    
    
                var sourceColumnId = sourceColumn.dataIndex;
                var targetColumnId = targetColumn.dataIndex;
    
    
    
    
                //dont drag onto myself
                if (sourceRecordData.TaskID == targetRecordData.TaskID && sourceColumnId == targetColumnId) {
                    ddSource.view.getStore().resumeEvents();
                    return false;
                }
                
         
                //need two passes or we will wipe data out due to the replace code below
                //pass one to add
                var counter = 0;
                targetRecord.beginEdit();
                targetRecord.set(targetColumnId, sourceRecordData[sourceColumnId]);
                targetRecord.endEdit();
    
    
    
    
                //pass two to delete
                counter = 0;
                sourceRecord.beginEdit();
    
    
                sourceRecord.set(sourceColumnId, '');
    
    
                sourceRecord.endEdit();
    
    
                ddSource.view.getStore().resumeEvents();
                return true;
            };
        </script>
    </head>
    <body>
        <form id="Form1" runat="server">
            <ext:ResourceManager ID="ResourceManager1" runat="server">        
    
    
            </ext:ResourceManager>
            
            <h1>Menu overflow bug</h1>
    
    
            <ext:Viewport ID="Viewport1" runat="server" Layout="FitLayout">
                <Items>
                    <ext:GridPanel 
                        ID="GridPanel1" 
                        runat="server" 
                        Title="Test"       
                        ColumnLines="true"                  
                        Layout="FitLayout">
                        <TopBar>
                            <ext:Toolbar  ID="Toolbar1" runat="server" EnableOverflow="true" >
                                <Items>
    
    
                                    <ext:Button ID="ButtonPrevious1" runat="server"  Icon="Tux"> 
                                    </ext:Button>
    
    
                                    <ext:ToolbarSeparator Hidden="true" ID="SingleSeparator" />
    
    
                                    <ext:ComboBox ID="test" 
                                            QueryMode="Local"
                                            ForceSelection="true"
                                            TriggerAction="All"
                                            EmptyText="Select an ..."
                                            DisplayField="text"
                                            ValueField="id"
                                            runat="server" 
                                            Width="350" >
    
    
                                    </ext:ComboBox>
    
    
                                    <ext:Button ID="ButtonNext" runat="server" Icon="ResultsetNext">
                                    </ext:Button>
    
    
                                    <ext:ToolbarSeparator />
                                    <ext:Label ID="TPeriod" runat="server" Html="<b>&nbsp;Period:</b>" />
    
    
                                    <ext:Button ID="ButtonPd" runat="server"  Icon="ResultsetPrevious">
                                    </ext:Button>
                                    <ext:ComboBox ID="testssdsdf" 
                                        runat="server" 
                                        ForceSelection="true"
                                        TriggerAction="All"
                                        Width="170" 
                                        DisplayField="dates"
                                        QueryMode="Local"
                                        ValueField="id" 
                                        Editable="false" >
                                        <Store>
                                            <ext:Store ID="Store2" runat="server">
                                                <Model>
                                                    <ext:Model ID="Model2" IDProperty="id" runat="server">
                                                        <Fields>
                                                            <ext:ModelField Name="id" Type="Int" />
                                                            <ext:ModelField Name="dates" Type="String"/>
                                                        </Fields>
                                                    </ext:Model>
                                                </Model>
                                            </ext:Store>
                                        </Store>
                                    </ext:ComboBox>
                                    <ext:Button ID="ButtonNex" runat="server" Icon="ResultsetNext">
                                    </ext:Button>
                                    <ext:ToolbarSeparator />
    
    
                                    <ext:Label ID="TiId" runat="server" Html="<b>&nbsp;Tid Id:</b>" />
    
    
                                    <ext:ToolbarSeparator />
                                    <ext:Label ID="Timetus" runat="server" Html="<b>&nbsp;Status:</b>" />
                                    <ext:ToolbarFill />
                                </Items>
                            </ext:Toolbar>
                        </TopBar>
                        <Store>
                            <ext:Store ID="Store1" runat="server">
                                <Model>
                                    <ext:Model ID="Model1" runat="server" IDProperty="TaskID">
                                        <Fields>
                                            <ext:ModelField Name="ProjectID" Type="Int" />
                                            <ext:ModelField Name="Name" />
                                            <ext:ModelField Name="TaskID" Type="Int" />
                                            <ext:ModelField Name="Description" />
                                            <ext:ModelField Name="Estimate" Type="Int" />
                                            <ext:ModelField Name="Rate" Type="Float" />
                                            <ext:ModelField Name="Cost" Type="Float" />
                                            <ext:ModelField Name="Due" Type="Date" />
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>
                        </Store>
                        <ColumnModel ID="ColumnModel1" runat="server">
                            <Columns>
                                <ext:Column ID="Column1"
                                    runat="server"
                                    TdCls="task"
                                    Text="Task"
                                    Sortable="true"
                                    DataIndex="Description"
                                    Hideable="false"
                                    Width="300">
                                </ext:Column>
                         
                                <ext:Column ID="Column2" runat="server" Text="Project" DataIndex="Name" Width="180" />
                         
                                <ext:DateColumn ID="DateColumn1"
                                    runat="server"
                                    Width="130"
                                    Text="Due Date"
                                    Sortable="true"
                                    DataIndex="Due"
                                    Format="MM/dd/yyyy">
                                </ext:DateColumn>
     
                                <ext:Column ID="Column3"
                                    runat="server"  
                                    Width="130"
                                    Text="Estimate"
                                    Sortable="true"
                                    DataIndex="Estimate">
                                </ext:Column>
                         
                                <ext:Column ID="Column4"
                                    runat="server"
                                    Width="130"
                                    Text="Rate"
                                    Sortable="true"
                                    DataIndex="Rate">
                                </ext:Column>
                         
                                <ext:Column
                                    runat="server"
                                    Width="130"
                                    ID="Cost"
                                    Text="Cost"
                                    Sortable="false"
                                    Groupable="false"
                                    DataIndex="Cost">
                                </ext:Column>
                            </Columns>                
                        </ColumnModel>           
                        <View>
                            <ext:GridView ID="GridView7" runat="server" StripeRows="true">
                                <Plugins>
                                    <ext:CellDragDrop ID="CellDragDrop1" runat="server" ApplyEmptyText="true" EnforceType="true" DDGroup="ddGroup" />
                                </Plugins>
                                <Listeners>
                                    <AfterRender Fn="onAfterRenderDragAndDrop" />
                                </Listeners>
                            </ext:GridView>
                        </View>
                        <Listeners>
                             <ItemMouseDown Fn="saveMouseDown" />
                        </Listeners>
                        <SelectionModel>
                            <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
                        </SelectionModel>
                    </ext:GridPanel>
                </Items>
            </ext:Viewport>
    
    
        <ext:DropTarget ID="DropTarget1"
                    runat="server"      
            Target="={Ext.getCmp('GridPanel1').getView()}"
            Group="ddGroup" >        
    
    
            <NotifyDrop Fn="notifyDrop2" />
            <NotifyOver Fn="notifyOver2" />
        </ext:DropTarget>
    
    
    
    
        </form>
      </body>
    </html>
    Last edited by Daniil; Nov 07, 2015 at 9:17 AM. Reason: [OPEN] [#933] [3.2.1]
  2. #2
    Hi @Z,

    Thank you for the report and the investigation!

    Please try this override:
    Ext.view.DragZone.override({
        init: function (id, sGroup, config) {
            var me = this,
                //triggerEvent = Ext.supports.touchScroll ? 'itemlongpress' : 'itemmousedown',
                triggerEvent = "itemmousedown",
                eventSpec = {
                    scope: me
                };
    
            eventSpec[triggerEvent] = me.onItemMouseDown;
            me.initTarget(id, sGroup, config);
            me.view.mon(me.view, eventSpec);
        }
    });
  3. #3
    much better. let me get this deployed for the customers to verify.
    Thanks!
    /Z
  4. #4
    customer verified that this fix is good and is working well.

    please flag as bug and commit to SVN
    /Z
  5. #5
    Created an Issue.
    https://github.com/extnet/Ext.NET/issues/933

    As for the fix, it was a fix for your scenario. But in general, the itemlongpress should not be ignored - otherwise it is not going to work for touch drag&drop.

    At the moment I don't see a good way to distinguish the cases automatically and use itemmousedown/itemlongpress accordingly.
  6. #6
    Please note that while this fix is good.... It causes a problem if you try to scroll.

    Load 500 records.... Then load in ipad. Try to scroll but it thinks u want to drag/drop.

    If (touch only) then longpress
    Else click

    Key is touch monitor with mouse should click. Ipad should be long press.

    Thoughts?
    /Z

Similar Threads

  1. [CLOSED] DOM Drag-Drop example initial drag height
    By electromorph in forum 3.x Legacy Premium Help
    Replies: 2
    Last Post: Jul 09, 2015, 1:36 PM
  2. [CLOSED] Drag and drop design and issues
    By ATLAS in forum 2.x Legacy Premium Help
    Replies: 7
    Last Post: Oct 10, 2014, 3:17 PM
  3. Replies: 0
    Last Post: Jun 12, 2014, 1:11 PM
  4. Drag Drop
    By designworxz in forum 1.x Help
    Replies: 0
    Last Post: Feb 20, 2009, 12:46 AM
  5. [CLOSED] MultiSelect with drag and drop, Drop listener
    By Jurke in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Jan 30, 2009, 9:25 AM

Posting Permissions