1

I know the jQuery UI API has snap, snapMethod and snapTolerance built in, but these are not going to work in this case.

Here is the problem I face: when dragging within a container, I want the draggable to snap to the edges of the container when within a certain distance. Calculating distances and triggering this is not an issue. It is getting the draggable to snap which I cannot get to work.

I expected something like: $draggable.position().left = 0; might snap it to the left edge of the parent container but it doesn't make any difference.

Here is a fiddle to demonstrate: https://jsfiddle.net/jwxrevL2/1/

JS:

//set draggable $('.drag').draggable({ drag: function(){ drag($(this)) }, containment: 'parent', }); //drag function drag( $draggable ){ var snap_tolerance = 10; //Draggable var d_top = $draggable.position().top; var d_middle = ($draggable.position().top+($draggable.height()/2)); var d_bottom = ($draggable.position().top+$draggable.height()); var d_left = $draggable.position().left; var d_center = ($draggable.position().left+($draggable.width()/2)); var d_right = ($draggable.position().left+$draggable.width()); //Wrapper var $wrapper = $('.wrapper'); var w_top = 0; var w_bottom = $wrapper.height(); var w_left = 0 var w_right = $wrapper.width(); //snap to left if( d_left <= (w_left+snap_tolerance )){ console.log('snap left'); $draggable.position().left = w_left; within_snap = true; } //snap to right if( d_right >= (w_right-snap_tolerance)){ console.log('snap right'); $draggable.position().left = (w_right-$draggable.width()); within_snap = true; } //snap to top if( d_top <= (w_top+snap_tolerance )){ console.log('snap top'); $draggable.position().top = w_top; within_snap = true; } //snap to bottom if( d_bottom >= (w_bottom-snap_tolerance )){ console.log('snap bottom'); $draggable.position().top = (w_bottom-$draggable.height()); within_snap = true; } }//end fn drag 

2 Answers 2

1

I've have managed to get it working. Although I must say I do not fully understand what is going on. These are the changes I've made (updated fiddle):

//set draggable $('.drag').draggable({ drag: function(e, ui){ drag($(this), ui) }, containment: 'parent', }); 

So on the drag event I pass the ui object as well as the jQuery object (I think, please correct me if I am wrong about the ui object) into the drag function.

//snap to left if( d_left <= (w_left+snap_tolerance )){ console.log('snap left'); ui.position.left = w_left; within_snap = true; } 

Then by updating the ui objects position.left property I can snap it into position.

Can anyone explain why it is different using ui rather than the jQuery object?

Sign up to request clarification or add additional context in comments.

Comments

0

Here's an example.

You need to specify a grid like so:

<script> $(function() { $( "#draggable4" ).draggable({ grid: [ 20, 20 ] }); $( "#draggable5" ).draggable({ grid: [ 80, 80 ] }); }); </script> 

https://jsfiddle.net/m3r2xra3/

1 Comment

Thanks, but the grid solution will not work in the application I am working on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.