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

Page 1 of 2 12 LastLast
  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
  7. #7
    Yes, it is exactly the problem I was talking about.

    Probably, this override is better in your scenarios:
    Ext.view.DragZone.override({
        init: function (id, sGroup, config) {
            var me = this,
                triggerEvent = (Ext.supports.touchScroll && !Ext.isWindows) ? 'itemlongpress' : 'itemmousedown',
                eventSpec = {
                    scope: me
                };
    
            eventSpec[triggerEvent] = me.onItemMouseDown;
            me.initTarget(id, sGroup, config);
            me.view.mon(me.view, eventSpec);
        }
    });
  8. #8
    Yikes!
    What about my chrome and FF users? How about Ext.isDesktop?

    Also, with viewport.autoscroll to false, on Android, the zoom in/out doesn't work consistently.

    Also can not do find docs for Ext.supports
    Zev.
  9. #9
    What about my chrome and FF users?
    Please clarify does something not work for them properly?

    How about Ext.isDesktop?
    Yes, that is a nice idea. There is no Ext.isDestop, but there is Ext.os.deviceType.
    http://docs.sencha.com/extjs/5.1/5.1...rty-deviceType

    Also, with viewport.autoscroll to false, on Android, the zoom in/out doesn't work consistently.
    Please clarify is that related to the drag&drop fix? If it doesn't, it is better to discuss it in an individual thread.

    Also can not do find docs for Ext.supports
    Please follow this link:
    http://docs.sencha.com/extjs/5.1/5.1...i/Ext.supports
  10. #10
    Hello @Z!

    Did you change your original code on this thread to work on touch devices, or is it still the code that you needed the fix (like Daniil's provided override) to make it work?

    I just tested your example on to-be-released Ext.NET 4.1.0 and the example worked:
    - on an android device with Chrome for Android 48
    - on a desktop with google chrome 49 in touch emulation in both 'mobile' and 'desktop with touch' user agent emulation modes!

    If your code above should not trigger "trigger" events due to the drag-drop limitation, I suppose this issue has been fixed!
    Fabrício Murta
    Developer & Support Expert
Page 1 of 2 12 LastLast

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