46

This is one situation where I hope someone replies to tell me I'm an idiot. But I continue to be amazed that jQueryUI drag\drop doesn't work with touch devices. I have not tested them all but I have tried iphone\ipad\android 2, 3&4 over the last year and nothing. Just tried the latest version on a new Android. Still nothing. Don't believe me, just visit the demo page on a mobile device and try to use the drag\drop examples. Nothing.

Is there a technical problem or core incompatibility in play here? A fix so easy that its not worth writing about? Do jQuery devs not use mobile devices? I have seen "fixes" posted here and there around Stack Overflow but they are all "hacks" and all the ones I've tried don't work.

I'm perplexed. Can someone shed some light on this issue?

Kara
  • 6,115
  • 16
  • 50
  • 57
Brian
  • 839
  • 1
  • 10
  • 14
  • I think it's more of an issue of target audience. jQuery UI wasn't originally written to handle mobile devices. It won't even play nicely with jQuery Mobile. some parts of it may still work well in mobile devices, but anything that has anything to do with dragging will fail. – Kevin B Dec 18 '12 at 19:59

4 Answers4

82

If you just want your current jQuery UI code to work with touch events, you can use the jQuery UI Touch Punch monkey patch.

The only "technical problem or core incompatibility" is that jQuery UI (1.x) only listens for mouse events, not touch events (See @ScottGonzales's response for the historical reason). jQuery touch punch, above, makes that change. You can even try some of the jQuery UI examples on that page, and they work. Generally, using Touch Punch is the currently accepted solution.

RafaSashi
  • 16,483
  • 8
  • 84
  • 94
forivall
  • 9,504
  • 2
  • 33
  • 58
  • 1
    "_Touch Punch monkey patch_" sounds – IvanM Mar 14 '18 at 21:09
  • 1
    Not the best solution: if the element to drag takes the whole viewport, using jQuery UI Touch Punch prevents the document to be scrolled. Can be even a problem with element you want to be only draggable horizontally with a container hiding overflow, as a draggable carousel. In this case, the carousel prevents user to scroll the document up and down. I prefer jQuery Touch (github.com/ajlkn/jquery.touch) which makes draggable possibly touch only on mobile (mouse gesture can be filtered) and does not prevent touch events to propagate (thus, document to be scrolled). – MaxAuray Nov 14 '18 at 10:30
  • 2
    @MaxAuray Your comment would make an excellent alternate answer to this question! Note that jquery.touch didn't exist in 2012, when i originally answered this >_ – forivall Jan 04 '19 at 00:13
  • 1
    I initially found touch punch wasn't working for me (due to Chrome 70 disabling ontouch APIs on desktop). I found solutions in https://github.com/furf/jquery-ui-touch-punch/issues/309. This change to line 14 fixed it in my case: $.support.touch = ('ontouchstart' in document || 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0); – Rob Powell Aug 23 '22 at 22:12
  • 1
    @RobPowell You can also find useful forks of touch punch using https://useful-forks.github.io/ - the most promising one I saw is https://github.com/AndrewDodd42/jquery-ui-touch-punch . Note that I haven't used jquery in a long time, so I havent evaulated them. – forivall Sep 27 '22 at 23:30
34

There's a long history behind why jQuery UI doesn't support touch devices, but it boils down to the fact that Touch Event was a non-standard WebKit-specific implementation. At the time, the future looked dreary. Apple held patents that nobody wanted to go near; as a result, Mozilla implemented their own touch event system with streams which never caught on. It wasn't clear what Microsoft and Opera would do. Paul Bakaus (the creator of jQuery UI) wanted to land iPhone support 4 years ago. I wanted to wait for an official standard.

Time passed, Mozilla abandoned their touch events and Microsoft implemented their own pointer events system. The W3C formed a Working Group to standardize Touch Events and investigate the Apple patents. The Touch Events Working Group has published a recommendation and disbanded. Microsoft eventually submitted a proposal to standardize Pointer Events and there is now a W3C Pointer Events Working Group.

We're currently working on a device-agnostic rewrite of all jQuery UI interactions which will be part of jQuery UI 2.0. Until then, you can use jQuery UI Touch Punch.

Earlier this year, I wrote about some of the history around Touch Events and why Pointer Events provide a better future. You can read about it on the jQuery blog.

Scott González
  • 1,917
  • 16
  • 10
  • Not the best solution: if the element to drag takes the whole viewport, using jQuery UI Touch Punch prevents the document to be scrolled. Can be even a problem with element you want to be only draggable horizontally with a container hiding overflow, as a draggable carousel. In this case, the carousel prevents user to scroll the document up and down. I prefer jQuery Touch (github.com/ajlkn/jquery.touch) which makes draggable possibly touch only on mobile (mouse gesture can be filtered) and does not prevent touch events to propagate (thus, document to be scrolled). – MaxAuray Nov 14 '18 at 10:30
0

Check out jQTouch

It's a jQuery plugin that helps bridge the event gaps between desktop and touch devices.

Jason Whitted
  • 4,059
  • 1
  • 16
  • 16
0

Using jQuery UI Touch Punch seems to be the the best approach.

<script src="../jquery-ui-1.13.0/external/jquery/jquery.js"></script>
<script src="../jquery-ui-1.13.0.custom/jquery-ui.min.js"></script>
<script src="../jquery-ui-1.13.0/jquery-ui.min.js"></script>
<script src="../jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"></script>

<link href="../bootstrap-5.1.1/css/bootstrap.min.css" rel="stylesheet" />

<script>
    $(function () {
        $("#sortable").sortable();
    });
</script>

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <ul id="sortable" class="list-group">
                <li class="list-group-item active">Item 1</li>
                <li class="list-group-item">Item 2</li>
                <li class="list-group-item">Item 3</li>
                <li class="list-group-item">Item 4</li>
                <li class="list-group-item">Item 5</li>
                <li class="list-group-item">Item 6</li>
                <li class="list-group-item">Item 7</li>
                <li class="list-group-item">Item 8</li>
            </ul>
        </div>
    </div>
</div>

https://jsfiddle.net/igorkrupitsky/cw5n0xku/1/

Igor Krupitsky
  • 787
  • 6
  • 9