I am trying to get JQuery Sortable to work but I have run into a slight usability problem.
The list that I am trying to sort is quite large (about 200 items). If the
I would take a look at the scroll, scrollSensativity, and scrollSpeed options.
You can do something like:
$("#sort").sortable({ scroll: true, scrollSensitivity: 100 });
or
$("#sort").sortable({ scroll: true, scrollSpeed: 100 });
or even
$("#sort").sortable({ scroll: true, scrollSensitivity: 100, scrollSpeed: 100 });
I could not get any of the other answers working. Using Chrome and a sortable grid that needs to scroll vertically when an item is being dragged to the top or bottom edge of the window.
NOTE: This only works for scrolling the entire window. This will not work if you have a scrollable section inside of the window and need to scroll that.
I was able to get the following working flawlessly:
var currentlyScrolling = false;
var SCROLL_AREA_HEIGHT = 40; // Distance from window's top and bottom edge.
$(".sortable").sortable({
scroll: true,
sort: function(event, ui) {
if (currentlyScrolling) {
return;
}
var windowHeight = $(window).height();
var mouseYPosition = event.clientY;
if (mouseYPosition < SCROLL_AREA_HEIGHT) {
currentlyScrolling = true;
$('html, body').animate({
scrollTop: "-=" + windowHeight / 2 + "px" // Scroll up half of window height.
},
400, // 400ms animation.
function() {
currentlyScrolling = false;
});
} else if (mouseYPosition > (windowHeight - SCROLL_AREA_HEIGHT)) {
currentlyScrolling = true;
$('html, body').animate({
scrollTop: "+=" + windowHeight / 2 + "px" // Scroll down half of window height.
},
400, // 400ms animation.
function() {
currentlyScrolling = false;
});
}
}
});
currentlyScrolling = false
SCROLL_AREA_HEIGHT = 40
sort: (event, ui) ->
return if currentlyScrolling
windowHeight = $( window ).height()
mouseYPosition = event.clientY
if mouseYPosition < SCROLL_AREA_HEIGHT # Scroll up.
currentlyScrolling = true
$( 'html, body' ).animate( { scrollTop: "-=" + windowHeight / 2 + "px" }, 400, () -> currentlyScrolling = false )
else if mouseYPosition > ( windowHeight - SCROLL_AREA_HEIGHT ) # Scroll down.
currentlyScrolling = true
$( 'html, body' ).animate( { scrollTop: "+=" + windowHeight / 2 + "px" }, 400, () -> currentlyScrolling = false )
I have removed overflow-y: scroll
from body
to resolve it.
You can trigger events based on the position returned by mouseMove. Here's a simple tutorial: http://jquery-howto.blogspot.com/2009/07/identifying-locating-mouse-position-in.html
This tutorial might help you get started: http://valums.com/vertical-scrolling-menu/ And this walks through the same effect: http://www.queness.com/resources/html/scrollmenu/index.html
Based on @marty 's answer, here is a fine tuned code that will: 1. Control speed of the scrolling 2. Will scroll down and scroll up without glitches. 3. Default speed is 7px at a time 4. movements of less than 7px will be ignored
var previousLocation, previousDelta;
$( ".selector" ).sortable({
sort: function(event, ui) {
var currentScrollTop = $(window).scrollTop(),
topHelper = ui.position.top,
delta = topHelper - currentScrollTop;
setTimeout(function() {
if((delta < 7 && delta >=0) || (delta > -7 && delta <=0))
return;
if(delta > 7){
delta = 7;
if((topHelper - previousDelta) < previousLocation){
delta = (delta * -1);
}
}
if(delta < -7){
delta = -7;
if((topHelper - previousDelta) > previousLocation){
delta = (delta * -1);
}
}
$(window).scrollTop(currentScrollTop + delta);
previousLocation = topHelper; previousDelta = delta;
}, 5);
}
});
I think that you can consider handling scrolling external to sortable. I suggest to use timer and 'out' event of sortable.
Here is piece of code based on jQueryUI demo page, you can use it as start point, if want to go this way:
$(function() {
var scroll = '';
var $scrollable = $("#sortable");
function scrolling(){
if (scroll == 'up') {
$scrollable.scrollTop($scrollable.scrollTop()-20);
setTimeout(scrolling,50);
}
else if (scroll == 'down'){
$scrollable.scrollTop($scrollable.scrollTop()+20);
setTimeout(scrolling,50);
}
}
$( "#sortable" ).sortable({
scroll:false,
out: function( event, ui ) {
if (!ui.helper) return;
if (ui.offset.top>0) {
scroll='down';
} else {
scroll='up';
}
scrolling();
},
over: function( event, ui ) {
scroll='';
},
deactivate:function( event, ui ) {
scroll='';
}
});
$( "#sortable").disableSelection();
});
Here is also working example: JSBIN
sorry
I did not lock example code and was destroyed incidentally. Now it's back to work.