Search code examples
iphoneandroidiosjquery-uijquery-ui-sortable

Jquery-ui sortable doesn't work on touch devices based on Android or IOS


Is there any fix to make Jquery-ui sortable work on touch devices based on Android or IOS?


Solution

  • The other answer is great but unfortunately it will only work on iOS devices.

    Also there was is a breakage caused by later versions of jquery.ui that meant that _touchEnd events were not correctly resetting an internal flag (mouseHandled) in mouse.ui and this was causing exceptions.

    Both of these problems should now be fixed with this code.

    /*
     * Content-Type:text/javascript
     *
     * A bridge between iPad and iPhone touch events and jquery draggable, 
     * sortable etc. mouse interactions.
     * @author Oleg Slobodskoi  
     * 
     * modified by John Hardy to use with any touch device
     * fixed breakage caused by jquery.ui so that mouseHandled internal flag is reset 
     * before each touchStart event
     * 
     */
    (function( $ ) {
    
        $.support.touch = typeof Touch === 'object';
    
        if (!$.support.touch) {
            return;
        }
    
        var proto =  $.ui.mouse.prototype,
        _mouseInit = proto._mouseInit;
    
        $.extend( proto, {
            _mouseInit: function() {
                this.element
                .bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
                _mouseInit.apply( this, arguments );
            },
    
            _touchStart: function( event ) {
                if ( event.originalEvent.targetTouches.length != 1 ) {
                    return false;
                }
    
                this.element
                .bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
                .bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );
    
                this._modifyEvent( event );
    
                $( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
                this._mouseDown( event );
    
                return false;           
            },
    
            _touchMove: function( event ) {
                this._modifyEvent( event );
                this._mouseMove( event );   
            },
    
            _touchEnd: function( event ) {
                this.element
                .unbind( "touchmove." + this.widgetName )
                .unbind( "touchend." + this.widgetName );
                this._mouseUp( event ); 
            },
    
            _modifyEvent: function( event ) {
                event.which = 1;
                var target = event.originalEvent.targetTouches[0];
                event.pageX = target.clientX;
                event.pageY = target.clientY;
            }
    
        });
    
    })( jQuery );