I am in need of "Sortable Drag & Drop" functionality and I'm using jQuery. I can't really use jQuery UI, because for this project it would be an overhead (I'd need to add many KB of JS and CSS only to use small part of functionality).
Is there any plugin that you could recommend or maybe a simple implementation path, that I can follow?
The solution must be as lightweight as possible, preferably based on jQuery/Sizzle or pure JavaScript.
For future generations: http://dragsort.codeplex.com/
A demo: http://cleesh.org/example (couldn't find one on the development website).
Minified it comes to 9KB in size.
You can build your own JQuery download on jqueryui.com without all the css/theme information. You can also strip out the widgets and effects and just use draggable/droppable.
Comes to about 30KB all in. Still too large?
Here is another one for future generations: http://johnny.github.com/jquery-sortable/.
It's only dependency is jQuery, has a nice feature set and comes in at 8kb minified.
a lot of time since this was asked, so maybe if you are thinking about an alternative to jquery UI this is a really good and easy to implement http://rubaxa.github.io/Sortable/
If you're sure not using a customized, minified and gzipped version jQueryUI which you can maintain and update...
...maybe one of the plugins from the following blog post fits your favor:
"17 jQuery Plugins for Easy and Efficient Reordering and Filtering Page Elements" http://www.tripwiremagazine.com/2010/03/17-jquery-plugins-for-easy-and-efficient-reordering-and-filtering-page-elements.html
examples from the blogpost: "List Reorder" (<10KB) or "Sortable table rows with jQuery – Draggable rows" (<3KB)
If you look at the jQuery UI source, jquery.ui.sortable.js
is a separate file, which I believe depends only on jquery.ui.core.js
, jquery.ui.widget.js
and jquery.ui.mouse.js
, although I haven't tested this. However, this still weighs in at 36KB minified.
You can try mine (http://jsfiddle.net/606bs750/16/). Unlimited number of blocks you can drag and sort.
Blocks will constrain to the parent.
<div id="parent" class="parent">
<button id="button1" class="button">Drag me 1</button>
<button id="button2" class="button">Drag me 2</button>
<button id="button3" class="button">Drag me 3</button>
<button id="button4" class="button">Drag me 4</button>
</div>
JQuery (only):
$(function() {
$('.button').mousedown(function(e) {
if(e.which===1) {
var button = $(this);
var button_id = button.attr('id');
var parent_height = button.parent().innerHeight();
var top = parseInt(button.css('top'));
var original_ypos = button.position().top; //original ypos
var drag_min_ypos = 0-original_ypos;
var drag_max_ypos = parent_height-original_ypos-button.outerHeight();
var drag_start_ypos = e.clientY;
var my_ypos = original_ypos;
//Set current order for all
$('.button').each(function(i) { $(this).attr('data-order',(i+1)); });
var prev_button = button.prev('.button'); var next_button = button.next('.button');
var prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
var next_button_ypos = next_button.length>0 ? next_button.position().top : '';
$('#log1').text('mousedown '+button_id+' original_ypos: '+original_ypos);
$('#log2').text('');
$('#log3').text('');
$(window).on('mousemove',function(e) {
//Move and constrain
button.addClass('drag');
var direction = my_ypos>button.position().top ? 'up' : 'down';
var new_top = top+(e.clientY-drag_start_ypos);
my_ypos = button.position().top;
button.css({top:new_top+'px'});
if(new_top<drag_min_ypos) { button.css({top:drag_min_ypos+'px'}); }
if(new_top>drag_max_ypos) { button.css({top:drag_max_ypos+'px'}); }
$('#log2').text('mousemove new_top: '+new_top+', my_ypos: '+my_ypos+', direction: '+direction);
//$('#log3').text('');
//Check position over others
if(direction=='down'&&next_button_ypos!='') {
if(my_ypos>next_button_ypos) { //crossed next button
$('#log3').text('dragged after '+next_button_ypos+' ('+next_button.attr('id')+')');
next_button.css({top:(parseInt(next_button.css('top'))-next_button.outerHeight(true))+'px'}); //up once
var tmp_order = next_button.attr('data-order');
next_button.attr('data-order',button.attr('data-order')); //switch order
button.attr('data-order',tmp_order);
prev_button = next_button; next_button = next_button.nextAll('.button:not(.drag)').first();
prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
next_button_ypos = next_button.length>0 ? next_button.position().top : '';
}
} else if(direction=='up'&&prev_button_ypos!='') {
if(my_ypos<prev_button_ypos) { //crossed prev button
$('#log3').text('dragged before '+prev_button_ypos+', '+prev_button.attr('id'));
prev_button.css({top:(parseInt(prev_button.css('top'))+prev_button.outerHeight(true))+'px'}); //down once
var tmp_order = prev_button.attr('data-order');
prev_button.attr('data-order',button.attr('data-order')); //switch order
button.attr('data-order',tmp_order);
next_button = prev_button; prev_button = prev_button.prevAll('.button:not(.drag)').first();
prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
next_button_ypos = next_button.length>0 ? next_button.position().top : '';
}
}
$('#log4').text('prev_button_ypos: '+prev_button_ypos+' ('+prev_button.attr('id')+'), next_button_ypos: '+next_button_ypos+' ('+next_button.attr('id')+')');
});
$(window).on('mouseup',function(e) {
if(e.which===1) {
$('.button').removeClass('drag');
$(window).off('mouseup mousemove');
//Reorder and reposition all
$('.button').each(function() {
var this_order = parseInt($(this).attr('data-order'));
var prev_order = $(this).siblings('.button[data-order="'+(this_order-1)+'"]');
if(prev_order.length>0) { $(this).insertAfter(prev_order); }
});
$('.button').css('top','0'); $('.button').removeAttr('data-order'); //reset
$('#log1').text('mouseup');
$('#log2').text('');
$('#log3').text('');
$('#log4').text('');
}
});
}
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With