views:

787

answers:

4

I have a problem with a jQuery UI 1.7.2 sortable list in Firefox 3.6, IE7-8 work fine. When I'm scrolled down a bit, the helper element seems to have an offset of the same height that I'm scrolled down from the mouse pointer which makes it impossible to see which item you originally started dragging. How do I fix this or work around the issue? If there is no fix what is a really good alternative drag-able plugin?

Here are my initialization parameters for the sortable.

$("#sortable").sortable( {placeholder: 'ui-state-highlight'  } );
$("#sortable").disableSelection();
+2  A: 

I managed to figure out a fix for this:

$( "items" ).sortable({
start: function (event, ui) {
 if( ui.helper !== undefined )
  ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() );
},
beforeStop: function (event, ui) {
 if( ui.offset !== undefined )
  ui.helper.css('margin-top', 0);
},
placeholder: 'placeholder-class'
});

Basically, you need to listen for the sortable's "start" event to add the browser's current scrollTop() value to the helper's position, and then you need to listen for the sortable's "beforeStop" event, to remove that offset before the item is officially placed back into the list at its new position.

Hope that's helpful to someone!

Jonathan Harris
+3  A: 

You also need to account for the fact this is specific to firefox, here is the snippet I'm using - I got directed the right way from Harris' solution. I encountered this problem w/o using the helper when the sortable was in a relatively positioned container.

  var options = { 
   handle: '.mover', 
   update:updateSorting 
 };
  var userAgent = navigator.userAgent.toLowerCase();
  if(userAgent.match(/firefox/)) {
    options["start"] = function (event, ui) { ui.item.css('margin-top', $(window).scrollTop() ); };
    options["beforeStop"] = function (event, ui) { ui.item.css('margin-top', 0 ); };
  }
  $("#" + list_id+"").sortable(options);
  $("#" + list_id+"").disableSelection();

You could also do this check on the server and then have 2 different calls depending on the browser.

Russell
Excellent, you saved me a lot of trouble here.
Dan Fuller
+1  A: 

If you want to prevent browser sniffing, the CSS only solution is to set the ul or a container style to overflow: auto. If you look at the source through firebug, it's the way jQuery does it in their example.

munch
A: 

I was seeing this issue and was able to solve it by removing the css rule position:relative from one of the containing divs on my page. See also: http://forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff

craig
yes. was same solution for me
zack