6

I have an image that I've set up with jQuery UI to be draggable. This works fine but now I'd like to be able to Shift-drag on the image to draw a box on the image and not have it move. So if the Shift key is held down I don't want to do the drag.

I've tried putting

if(e.shiftKey)return; 

at the top of the drag_start, dragging, and drag_stop functions but this doesn't do anything because the drag operation seems to be done internally in jQuery UI and the calls to drag_start, dragging and drag_stop are just courtesy calls to let you know what jQueryUI is currently doing.

Is there a way to disable the drag if the Shift key is held down?

Thanks

(For more information on this see my "answer" farther below with a jsfiddle.)

Steve
  • 4,534
  • 9
  • 52
  • 110

3 Answers3

6

How about on start_drag if shift key then return false; (don't initiate drag)

function box_start_drag(e, ui) {
    if(e.shiftKey)
        return false;
}

Fiddle

Or to stop dragging any time shift is held down. Put the return false in the drag method as Dom suggests in the comments below.

Trevor
  • 16,080
  • 9
  • 52
  • 83
  • 2
    I suggest returning false on `drag` rather than `start`(dragstart): [demo](http://jsfiddle.net/dirtyd77/JqsK5/); that way, holding shift at any point will stop dragging. – Dom Mar 06 '14 at 06:47
  • @Dom Good call, you can certainly do that instead. – Trevor Mar 06 '14 at 13:48
  • Thanks Trevor! I actually had the answer - almost. I had if(e.shiftKey)return; at the top of drag_start but not if(e.shiftKey)return false; If you have a moment could you explain why the magic word "false" makes it all work? - Thanks – Steve Mar 08 '14 at 23:53
  • Dom, Thanks for this idea but in my case the decision is made when the drag starts to go one way or the other. There's no switching once you start, so Trevor's solution is fine. – Steve Mar 09 '14 at 00:09
  • @Steve setting `return;` exits the function only. But you need to specify `false` in order to let jQuery ui know that you don't want to initiate the drag. This Question may be useful as well http://stackoverflow.com/questions/5596404/return-false-the-same-as-return – Trevor Mar 09 '14 at 01:15
0

I am pretty sure this is how it is done, but I haven't tested it. You need a key listener, and you can place it wherever, on the element you are dragging, or on the body in general. Then when you hit the shift key, it will turn the switch on or off.

var shift=false;
$("body").keydown(function(e){
    if(e.shiftKey){
        shift=true;
    }
}).keyup(function(e){
    if(e.shiftKey && shift){
        shift=false;
    }
});

$("#draggable").draggable({
    drag:function(e){
        if(shift){
            return;
        }
    }
});

One problem with this though is that if the shift key is let go, I believe you will still be dragging... Again, this is not tested, but should get you up and running.

Tim Withers
  • 12,072
  • 5
  • 43
  • 67
  • I'm not seeing how that's any different than putting if(e.shift)return at the top of the current drag function. Killing the drag function doesn't kill the drag. If you just do a $('#dragme').draggable() you'll get a drag, even though there is no drag function. – Steve Mar 03 '14 at 06:01
0

I thought a solution might be to have the dragging handler keep setting the position back to the original position if Shift was held down. The js fiddle here - http://jsfiddle.net/26Gf4/ - trys to do that, with the image replaced by a div to make things simpler, but it doesn't work. The console.log says the box is being put back to the original position at each dragging entry, but the box keeps moving with the drag. The same reset code in the box_stop_drag() handler works ok.

var drag_startPosition;

var box_dragOps = { 
        start : box_start_drag,
        drag  : box_dragging,
        stop : box_stop_drag
    };

$('#box').draggable(box_dragOps);


function box_start_drag(e, ui) {
    drag_startPosition = ui.position;
}

function box_dragging(e,ui) {

    if(e.shiftKey) {
        ui.helper.css({'top':drag_startPosition.top, 'left':drag_startPosition.left});
        console.log("box_dragging: setting position back to top="+drag_startPosition.top+" left="+drag_startPosition.left); 
        return;
    }
}

function box_stop_drag(e, ui) {
    ui.helper.css({'top':drag_startPosition.top, 'left':drag_startPosition.left});
        console.log("box_stop_drag: setting position back to top="+drag_startPosition.top+" left="+drag_startPosition.left); 
        return;
}
Steve
  • 4,534
  • 9
  • 52
  • 110