Question

How would you setup touch events to the draggable class, so that it works on iOS (iPad's, iPhone's, etc)? I have read How can I make a jQuery UI 'draggable()' div draggable for touchscreen?, which has lots of options for jQuery, but not sure how to apply that to Scriptaculous. Any help would be appreciated. Thanks.

Was it helpful?

Solution

You can do it by editing dragdrop.js as mention here:

In Draggables:

  register: function(draggable) {
    if(this.drags.length == 0) {
      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
      this.eventKeypress  = this.keyPress.bindAsEventListener(this);


      Event.observe(document, "mouseup", this.eventMouseUp);
      Event.observe(document, "mousemove", this.eventMouseMove);
      Event.observe(document, "keypress", this.eventKeypress);


      Event.observe(document, "touchstart", this.eventKeypress);
      Event.observe(document, "touchmove", this.eventMouseMove);
      Event.observe(document, "touchend", this.eventMouseUp);
    }
    this.drags.push(draggable);
  },


  unregister: function(draggable) {
    this.drags = this.drags.reject(function(d) { return d==draggable });
    if(this.drags.length == 0) {
      Event.stopObserving(document, "touchstart", this.eventKeypress);
      Event.stopObserving(document, "touchmove", this.eventMouseMove);
      Event.stopObserving(document, "touchend", this.eventMouseUp);


      Event.stopObserving(document, "mouseup", this.eventMouseUp);
      Event.stopObserving(document, "mousemove", this.eventMouseMove);
      Event.stopObserving(document, "keypress", this.eventKeypress);
    }
  },

In Draggable:

initialize:
...
    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
    Event.observe(this.handle, "mousedown", this.eventMouseDown);
      Event.observe(this.handle, "touchstart", this.eventMouseDown);


    Draggables.register(this);
  },


  destroy: function() {
    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
    Event.stopObserving(this.handle, "touchstart", this.eventMouseDown);
    Draggables.unregister(this);
  },

...

initDrag: function(event) {
    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
      Draggable._dragging[this.element]) return;
    if(Event.isLeftClick(event) || event.type == "touchstart") {

Along with editing prototype.js:

function pointerX(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollLeft: 0 };


    if (event.changedTouches) return (event.changedTouches[0].clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));


    return event.pageX || (event.clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));
  }


  function pointerY(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollTop: 0 };


    if (event.changedTouches) return (event.changedTouches[0].clientY +
      (docElement.scrollTop || body.scrollTop) -
      (docElement.clientTop || 0));


    return  event.pageY || (event.clientY +
       (docElement.scrollTop || body.scrollTop) -
       (docElement.clientTop || 0));
  }

OTHER TIPS

I think, you have to use parseInt function for X,Y coordinates, because I have some problem with Chrome browser on Android-it put something like 23.45435435345345345345345 to coordinates.

//Add parseInt ----------------[start]  
if (event.changedTouches) return (parseInt(event.changedTouches[0].clientY +
      (docElement.scrollTop || body.scrollTop) -
      (docElement.clientTop || 0),10));
//Add parseInt ----------------[end]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top