Search code examples
jqueryjquery-uidraggable

How to make jQuery draggable with fixed X and Y axis?


I am wondering if there is a way to make the jQuery draggable to only drag straight up, down and left, right. I want to prevent the user from dragging a div diagonally. Using the grid option in the draggable UI is not possible in my situation.

http://jqueryui.com/demos/draggable/#constrain-movement

How is this possible?

Thanks!


Solution

  • I wrote a plugin that allows moving a draggable in both axes. It gets the job done but it would be better-implemented as a jQuery UI widget rather than a simple jQuery plugin.

    Hosted Demo: http://jsbin.com/ugadu/1 (Editable via http://jsbin.com/ugadu/1/edit)

    Plugin code:

    $.fn.draggableXY = function(options) { 
      var defaultOptions = { 
        distance: 5, 
        dynamic: false 
      }; 
      options = $.extend(defaultOptions, options); 
    
      this.draggable({ 
        distance: options.distance, 
        start: function (event, ui) { 
          ui.helper.data('draggableXY.originalPosition', ui.position || {top: 0, left: 0}); 
          ui.helper.data('draggableXY.newDrag', true); 
        }, 
        drag: function (event, ui) { 
          var originalPosition = ui.helper.data('draggableXY.originalPosition'); 
          var deltaX = Math.abs(originalPosition.left - ui.position.left); 
          var deltaY = Math.abs(originalPosition.top - ui.position.top); 
    
          var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag'); 
          ui.helper.data('draggableXY.newDrag', false); 
    
          var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax'); 
          ui.helper.data('draggableXY.xMax', xMax); 
    
          var newPosition = ui.position; 
          if(xMax) { 
            newPosition.top = originalPosition.top; 
          } 
          if(!xMax){ 
            newPosition.left = originalPosition.left; 
          } 
    
          return newPosition; 
        } 
      }); 
    };