Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop multiple items in front of first item doesn't work. #32

Open
ChaosCrafter opened this issue Jul 29, 2015 · 1 comment
Open

Drop multiple items in front of first item doesn't work. #32

ChaosCrafter opened this issue Jul 29, 2015 · 1 comment

Comments

@ChaosCrafter
Copy link

This error can be viewed in the fiddle http://jsfiddle.net/sCxpu/2/
If you select a single item you can drag it throughout the grid.
If you select 2 items you can drag them anywhere, but if you drag them over the first item it will alternate between showing the placeholder box in its original position, or in one of first or second position.
If you select 3 or more items it just shows the placeholder in its original position for the left side of the first item, or in position 2 for the right side.
Even if we can't fix it, I'd love to find a workaround.

@ChaosCrafter
Copy link
Author

Here's an alternate version, taking an option parameter multigrid=true if you are not doing grids, and instead of moving items it hides all selected items.

/**

!function($) {

$.fn.multiselectable = function(options) {
    if (!options) {
        options = {}
    }
    options = $.extend({}, $.fn.multiselectable.defaults, options);

    function mouseDown(e) {
        var item = $(this),
            parent = item.parent(),
            myIndex = item.index();

        var prev = parent.find('.multiselectable-previous');
        // If no previous selection found, start selecting from first selected item.
        prev = prev.length ? prev : $(parent.find('.' + options.selectedClass)[0]).addClass('multiselectable-previous');
        var prevIndex = prev.index();

        if (e.ctrlKey || e.metaKey) {
            if (item.hasClass(options.selectedClass)) {
                item.removeClass(options.selectedClass).removeClass('multiselectable-previous')
                if (item.not('.child').length) {
                    item.nextUntil(':not(.child)').removeClass(options.selectedClass);
                }
            }
            else {
                parent.find('.multiselectable-previous').removeClass('multiselectable-previous');
                item.addClass(options.selectedClass).addClass('multiselectable-previous')
                if (item.not('.child').length) {
                    item.nextUntil(':not(.child)').addClass(options.selectedClass);
                }
            }
        }

        if (e.shiftKey) {
            var last_shift_range = parent.find('.multiselectable-shift');
            last_shift_range.removeClass(options.selectedClass).removeClass('multiselectable-shift');

            var shift_range;
            if (prevIndex < myIndex) {
                shift_range = item.prevUntil('.multiselectable-previous').add(prev).add(item);
            }
            else if (prevIndex > myIndex) {
                shift_range = item.nextUntil('.multiselectable-previous').add(prev).add(item);
            }
            shift_range.addClass(options.selectedClass).addClass('multiselectable-shift');
        }
        else {
            parent.find('.multiselectable-shift').removeClass('multiselectable-shift');
        }

        if (!e.ctrlKey && !e.metaKey && !e.shiftKey) {
            parent.find('.multiselectable-previous').removeClass('multiselectable-previous');
            if (!item.hasClass(options.selectedClass)) {
                parent.find('.' + options.selectedClass).removeClass(options.selectedClass);
                item.addClass(options.selectedClass).addClass('multiselectable-previous');
                if (item.not('.child').length) {
                    item.nextUntil(':not(.child)').addClass(options.selectedClass);
                }
            }
        }

        options.mousedown(e, item);
    }

    function click(e) {
        if ( $(this).is('.ui-draggable-dragging') ) {
            return;
        }

        var item = $(this), parent = item.parent();

        // If item wasn't draged and is not multiselected, it should reset selection for other items.
        if (!e.ctrlKey && !e.metaKey && !e.shiftKey) {
            parent.find('.multiselectable-previous').removeClass('multiselectable-previous');
            parent.find('.' + options.selectedClass).removeClass(options.selectedClass);
            item.addClass(options.selectedClass).addClass('multiselectable-previous');
            if (item.not('.child').length) {
                item.nextUntil(':not(.child)').addClass(options.selectedClass);
            }
        }

        options.click(e, item);
    }

    return this.each(function() {
        var list = $(this);

        if (!list.data('multiselectable')) {
            list.data('multiselectable', true)
                .delegate(options.items, 'mousedown', mouseDown)
                .delegate(options.items, 'click', click)
                .disableSelection();
        }
    })
};

$.fn.multiselectable.defaults = {
    click: function(event, elem) {},
    mousedown: function(event, elem) {},
    selectedClass: 'selected',
    items: 'li'
};

$.fn.hiddenSelected = false;

$.fn.multisortable = function(options) {
    if (!options) {
        options = {}
    }
    var settings = $.extend({}, $.fn.multisortable.defaults, options);

    function regroup(item, list) {
        if (list.find('.' + settings.selectedClass).length > 0) {
            var myIndex = item.data('i');

            var itemsBefore = list.find('.' + settings.selectedClass).filter(function() {
                return $(this).data('i') < myIndex
            }).css({
                    position: '',
                    width: '',
                    left: '',
                    top: '',
                    zIndex: ''
                });

            item.before(itemsBefore);

            var itemsAfter = list.find('.' + settings.selectedClass).filter(function() {
                return $(this).data('i') > myIndex
            }).css({
                    position: '',
                    width: '',
                    left: '',
                    top: '',
                    zIndex: ''
                });

            item.after(itemsAfter);

            setTimeout(function() {
                itemsAfter.add(itemsBefore).addClass(settings.selectedClass);
            }, 0);
        }
    }

    return this.each(function() {
        var list = $(this);

        //enable multi-selection
        list.multiselectable({
            selectedClass: settings.selectedClass,
            click: settings.click,
            items: settings.items,
            mousedown: settings.mousedown
        });

        //enable sorting
        options.cancel = settings.items + ':not(.' + settings.selectedClass + ')';
        options.placeholder = settings.placeholder;
        options.start = function(event, ui) {
            if (ui.item.hasClass(settings.selectedClass)) {
                var parent = ui.item.parent();

                //assign indexes to all selected items
                parent.find('.' + settings.selectedClass).each(function(i) {
                    $(this).data('i', i);
                });

                if (settings.configurePlaceholder) {
                    settings.configurePlaceholder(ui,settings);
                } else {
                    // adjust placeholder size to be size of items
                    var height = parent.find('.' + settings.selectedClass).length * ui.item.outerHeight();
                    ui.placeholder.height(height);
                }
            }

            settings.start(event, ui);
        };

        options.stop = function(event, ui) {
            regroup(ui.item, ui.item.parent());
            $.fn.hiddenSelected = false;
            settings.stop(event, ui);
        };

        options.sort = function (event, ui) {
            var parent = ui.item.parent(),
                myIndex = ui.item.data('i'),
                top = parseInt(ui.item.css('top').replace('px', '')),
                left = parseInt(ui.item.css('left').replace('px', ''));

            // fix to keep compatibility using prototype.js and jquery together
            $.fn.reverse = Array.prototype._reverse || Array.prototype.reverse

            if (settings.multigrid === true) {
                if ($.fn.hiddenSelected === false) {
                    $('.' + settings.selectedClass, parent).css('display', 'none');
                    $.fn.hiddenSelected = true;
                }
            } else {
                var height = 0;
                $('.' + settings.selectedClass, parent).filter(function() {
                    return $(this).data('i') < myIndex;
                }).reverse().each(function() {
                        height += $(this).outerHeight();
                        $(this).css({
                            left: left,
                            top: top - height,
                            position: 'absolute',
                            zIndex: 1000,
                            width: ui.item.width()
                        })
                    });

                height = ui.item.outerHeight();
                $('.' + settings.selectedClass, parent).filter(function() {
                    return $(this).data('i') > myIndex;
                }).each(function() {
                        var item = $(this);
                        item.css({
                            left: left,
                            top: top + height,
                            position: 'absolute',
                            zIndex: 1000,
                            width: ui.item.width()
                        });

                        height += item.outerHeight();
                    });
            }
            settings.sort(event, ui);
        };

        options.receive = function(event, ui) {
            regroup(ui.item, ui.sender);
            settings.receive(event, ui);
        };

        list.sortable(options).disableSelection();
    })
};

$.fn.multisortable.defaults = {
    start: function(event, ui) {},
    stop: function(event, ui) {},
    sort: function(event, ui) {},
    receive: function(event, ui) {},
    click: function(event, elem) {},
    mousedown: function(event, elem) {},
    selectedClass: 'selected',
    placeholder: 'placeholder',
    items: 'li'
};

}(jQuery);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant