AshesOfOwls / jquery.shapeshift

A dynamic grid system with drag and drop functionality.
http://ashesofowls.github.com/jquery.shapeshift/
MIT License
1.67k stars 312 forks source link

Shuffling elements gives an error when dragging them (after the Shuffle) #37

Closed cauli closed 11 years ago

cauli commented 11 years ago

Hello, I am trying to randomize the position of the elements in my grid. However, after I shuffle the position in the DOM and rearrange them, I get the same error as Issue #33 when I try to drag one of them.

Uncaught TypeError: Cannot read property 'left' of undefined
ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
AshesOfOwls commented 11 years ago

I am a little behind on getting to these issues. I just wanted to say I noticed it and I'll try to get it as soon as I have some free time.

cauli commented 11 years ago

I'll tinker with it some more time tomorrow. If I find a solution I'll post it here (or make a pull request). Thanks McPants!

cauli commented 11 years ago

Getting closer:

The problem happens because the shuffling method stores all tiles in a array by cloning them with clone(true), that also clones their binded events, the replacing each with replaceWith(arrayItem[i]).

$.fn.shuffle = function() {

            var allElems = this.get(),
                getRandom = function(max) {
                    return Math.floor(Math.random() * max);
                },
                shuffled = $.map(allElems, function(){
                    var random = getRandom(allElems.length),
                        randEl = $(allElems[random]).clone(true)[0];
                    allElems.splice(random, 1);
                    return randEl;
               });

            this.each(function(i){
                $(this).replaceWith($(shuffled[i]));
            });

            return $(shuffled);
        };

If I only rearrange the items within the console (via Chrome), then trigger ss-rearrange, no problem occurs. If I clone the items with .clone(false), then they still drag around, but they not conform to the shapeshift grid anymore.

cauli commented 11 years ago

Workaround: use .clone(false) in the shuffling method then reinitialize shapeshift with

$(".container").shapeshift(myShapeshiftOptions);

Shuffling method after the change:

$.fn.shuffle = function() {

            var allElems = this.get(),
                getRandom = function(max) {
                    return Math.floor(Math.random() * max);
                },
                shuffled = $.map(allElems, function(){
                    var random = getRandom(allElems.length),
                        randEl = $(allElems[random]).clone(false)[0];
                    allElems.splice(random, 1);
                    return randEl;
               });

            this.each(function(i){
                $(this).replaceWith($(shuffled[i]));
            });

            return $(shuffled);
        };

The problem of this approach is that the shuffle can't be animated. But hey, it works!

How to use it:

$('.container li').shuffle();
$(".container").shapeshift(myShapeshiftOptions);

Then reinitialize all events you assigned to the li elements, if any.

AshesOfOwls commented 11 years ago

Excellent, thanks for posting your workarounds.

I am going to keep this issue open because I feel like shuffling items could be a useful built in feature for Shapeshift and I will mark it for 3.0.

webwerx commented 11 years ago

great.

AshesOfOwls commented 11 years ago

This is now in version 2.0 thanks to Cauli.

To shuffle, trigger "ss-shuffle" on the container element.

See the documentation here for a more detailed explanation.