Skip to main content

Search and Top Navigation

#5740 closed feature (duplicate)

Opened June 18, 2010 07:54PM UTC

Closed October 27, 2010 07:52PM UTC

Last modified October 03, 2012 04:42PM UTC

Drop/release fails on mobile platforms

Reported by: woodpile Owned by:
Priority: major Milestone: 2.0.0
Component: ui.droppable Version: 1.8.2
Keywords: mobile touch jquery ui droppable Cc:
Blocked by: Blocking:
Description

Using mobile safari on iPod Touch and iPad, using a draggable/droppable or a sortable, dragging works fine, but dropping fails. It is left hovering over where the touch was released. Touching the screen again where you want it dropped causes the drop to complete, but that's not proper.

I made use of Ross Boucher's stuff (http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/) with Scriptaculous and it works great. Using the same code with jQuery UI, not the same results. I'm primarily using Sortables, but also draggables/droppables. The point is that the browser is connecting to events fine, but jQuery UI is not responding to the right events.

This patch: http://dev.jqueryui.com/ticket/4143 is interesting, but incomplete as it only works for iPhones. Remove the iPhone parts and make it more generic for any mobile/touch platform and it becomes a starting point.

Attachments (1)
  • test.html (3.1 KB) - added by woodpile June 18, 2010 08:12PM UTC.

    Test case.

Change History (9)

Changed June 18, 2010 08:13PM UTC by woodpile comment:1

I added a test case. Run that on mobile safari on a touch device and behavior is replicated. Dragging works, dropping does not without release and additional touch. I can help with any testing needed.

Changed August 10, 2010 06:05PM UTC by davep comment:2

The TouchList object is empty on touchend, I was able to fix the above issue by using the last TouchList object when e.touches[0] is undefined.

Adding something like this:

      if (first != undefined) {
      	lastTouch = first;
      } else {
      	first = lastTouch;
      }

Should fix the above issue, for now :)

Changed August 10, 2010 06:35PM UTC by davep comment:3

a couple other things..

You can get away with e.preventDefault() only being on the touchmove event, i had to do this so some other links would remain clickable.

some css you can add for webkit:


* {
  -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
  -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
  -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
  -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
}

Changed August 10, 2010 06:39PM UTC by woodpile comment:4

Replying to [comment:2 davep]:

The TouchList object is empty on touchend, I was able to fix the above issue by using the last TouchList object when e.touches[0] is undefined. Adding something like this:
>       if (first != undefined) {
>       	lastTouch = first;
>       } else {
>       	first = lastTouch;
>       }
> 
Should fix the above issue, for now :)

Where might I add that? I dl'd the full UI and cannot find any pertinent strings. I've no objection to maintaining a local copy briefly, but would much prefer to see this fixed in the real codebase and available on google cdn. Also, I have all that css in already for webkit/mobile safari. Any help appreciated. Thanks!

Changed August 10, 2010 08:06PM UTC by davep comment:5

My slightly updated event handler


 var lastTouch;

 function handleTouchEvent(e) {
  
  var touches = e.changedTouches,
   first = e.touches[0],
   type = '';
  
  // e.touches[0] is empty on touchend, use the last TouchList object instead
  if (first != undefined) {
   lastTouch = first;
  } else {
   first = lastTouch;
  }
   
  switch (e.type) {
   case 'touchstart':  type='mousedown'; break;
   case 'touchmove':   type='mousemove'; e.preventDefault(); break;
   case 'touchend':    type='mouseup';   break;
   default: return;
  }

  //initMouseEvent(type, canBubble, cancelable, view, clickCount,
  //           screenX, screenY, clientX, clientY, ctrlKey,
  //           altKey, shiftKey, metaKey, button, relatedTarget);
  var se = document.createEvent('MouseEvent');
  se.initMouseEvent(type, true, true, window, 1,
           first.screenX, first.screenY,
           first.clientX, first.clientY,
           false, false, false, false,
           0/*left*/, null);
  first.target.dispatchEvent(se);
  
  return;
 }

Note that i only prevent default behavior on touchmove, which works better for my needs.

Changed August 10, 2010 08:21PM UTC by woodpile comment:6

Replying to [comment:5 davep]:

My slightly updated event handler Note that i only prevent default behavior on touchmove, which works better for my needs.

Awesome! That did it for me. Thank you very much! I also backed off the preventDefault to just touchmove and it works fine. Thanks again!

Changed October 19, 2010 03:23PM UTC by scottgonzalez comment:7

priority: blockermajor
type: bugfeature

Changed October 27, 2010 07:52PM UTC by scottgonzalez comment:8

resolution: → duplicate
status: newclosed

Duplicate of #4143.

Changed October 03, 2012 04:42PM UTC by scottgonzalez comment:9

milestone: 1.next2.0.0