/* * HTML5 Sortable jQuery Plugin * http://farhadi.ir/projects/html5sortable * * Copyright 2012, Ali Farhadi * Released under the MIT license. */ (function ($) { var dragging, placeholders = $(); $.fn.sortable = function (options) { var method = String(options); options = $.extend({ connectWith: false, placeholderClass: '' }, options); return this.each(function () { if (/^enable|disable|destroy$/.test(method)) { var dragitems = $(this).children($(this).data('items')).attr('draggable', method == 'enable'); if (method == 'destroy') { dragitems.add(this).removeData('connectWith items') .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s'); } return; } var isHandle, parent, index, items = $(this).children(options.items); var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : /^tbody$/i.test(this.tagName) ? 'tr' : 'div') + ' class="sortable-placeholder ' + options.placeholderClass + '">').html(' '); items.find(options.handle).mousedown(function () { isHandle = true; }).mouseup(function () { isHandle = false; }); $(this).data('items', options.items) placeholders = placeholders.add(placeholder); if (options.connectWith) { $(options.connectWith).add(this).data('connectWith', options.connectWith); } items.attr('draggable', 'true').on('dragstart.h5s', function (e) { if (options.handle && !isHandle) { return false; } isHandle = false; var dt = e.originalEvent.dataTransfer; dt.effectAllowed = 'move'; dt.setData('Text', 'dummy'); index = (dragging = $(this)).addClass('sortable-dragging').index(); parent = dragging.parent(); }).on('dragend.h5s', function () { if (!dragging) { return; } dragging.removeClass('sortable-dragging').show(); placeholders.detach(); if (index != dragging.index()) { dragging.parent().trigger('sortupdate', { item: dragging }); } if (!dragging.parent().is(parent)) { dragging.parent().trigger('sortconnect', { item: dragging }); } dragging = null; }).not('a[href], img').on('selectstart.h5s', function () { this.dragDrop && this.dragDrop(); return false; }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function (e) { if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) { return true; } if (e.type == 'drop') { e.stopPropagation(); placeholders.filter(':visible').after(dragging); dragging.trigger('dragend.h5s'); return false; } e.preventDefault(); e.originalEvent.dataTransfer.dropEffect = 'move'; if (items.is(this)) { if (options.forcePlaceholderHeight || options.forcePlaceholderSize) { placeholder.height(dragging.outerHeight()); } if (options.forcePlaceholderWidth || options.forcePlaceholderSize) { placeholder.width(dragging.outerWidth()); } dragging.hide(); $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder); placeholders.not(placeholder).detach(); } else if (!placeholders.is(this) && !$(this).children(options.items).length) { placeholders.detach(); $(this).append(placeholder); } return false; }); }); }; })(jQuery);