Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draggable jQuery on Phonegap android

I'm having some problems while implementing jQuery Draggable http://jqueryui.com/demos/draggable/ on Android. I've created the html code and tested it using my browser. Then I compiled it on build.phonegap.com. After getting the .apk I installed it on my xperia x8 which is using Android 2.2 Froyo. The application ran well, but when I dragged the object it won't move.. Is there something wrong with my method? Thanks

like image 861
justmyfreak Avatar asked May 19 '11 04:05

justmyfreak


4 Answers

This code maps touchstart, touchmove and touchend to their appropriate mouse events: There is still a bug with touchstart / mousedown, because the coordinates cannot be mapped directly.

My idea to fix this is to delay the mousedown dispatch until a touchmove occurs and then dispatch both mouse events with the coordinates of touchmove.

var mouseEventTypes = {
    touchstart : "mousedown",
    touchmove : "mousemove",
    touchend : "mouseup"
};

for (originalType in mouseEventTypes) {
    document.addEventListener(originalType, function(originalEvent) {
        event = document.createEvent("MouseEvents");
        touch = originalEvent.changedTouches[0];
        event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true,
                window, 0, touch.screenX, touch.screenY, touch.clientX,
                touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey,
                touch.metaKey, 0, null);
        originalEvent.target.dispatchEvent(event);
    });
}
like image 51
Nappy Avatar answered Nov 12 '22 23:11

Nappy


I use some script but forget where i take it:

 *
 * Copyright 2011, Dave Furfero
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * Depends:
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 */
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);

It work perfect with jquery-ui. U just need to add it to your html code like js library

like image 33
user3111850 Avatar answered Nov 12 '22 23:11

user3111850


To make clicks also work...

            var mouseEventTypes = {
                touchstart : "mousedown",
                touchmove : "mousemove",
                touchend : "mouseup",
                click : clickEvent
            };

            for(originalType in mouseEventTypes) {
                document.addEventListener(originalType, function(originalEvent) {
                    if (originalEvent.type != 'click' && originalEvent.type != 'touchstart')
                        originalEvent.preventDefault();
                    event = document.createEvent("MouseEvents");
                    touch = originalEvent.changedTouches[0];
                    event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey, touch.metaKey, 0, null);
                    originalEvent.target.dispatchEvent(event);
                    event.preventDefault();
                });
like image 1
Bart Avatar answered Nov 12 '22 21:11

Bart


I used mixture of solutions above and realized that it helped with draggable elements, but it also made some elements in my project without ability to trigger click events on them, because the code above was preventing touchend events. I solved this problem. My version keeps draggable elements working and also keeps ability of other document elements to receive click events:

(function() {
function init() {
    var mouseEventTypes = {
        touchstart : "mousedown",
        touchmove : "mousemove",
        touchend : "mouseup"
    };

    for (originalType in mouseEventTypes) {
        document.addEventListener(originalType, function(originalEvent) {
            if(originalEvent.type == 'click')
                return;
            if (originalEvent.type != 'touchstart' && originalEvent.type !='touchend'){
                originalEvent.preventDefault();
            }
            event = document.createEvent("MouseEvents");
            touch = originalEvent.changedTouches[0];
            event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey, touch.metaKey, 0, null);
            originalEvent.target.dispatchEvent(event);
            event.preventDefault();         
        });
    }
}

init();
})();

Maybe it will help someone with similar issue. This problem with draggable elements occured only on my Galaxy Tab GT-P5110, Android version 4.0.4.

like image 1
Andrej Lucansky Avatar answered Nov 12 '22 23:11

Andrej Lucansky