Created
February 10, 2013 22:53
-
-
Save ultimatedelman/4751407 to your computer and use it in GitHub Desktop.
A CodePen by Jason Edelman. Isotope + JQuery UI Sortable - Naysayers will tell you it can't be done. But that's why they're naysayers and not yaydoers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ul> | |
<li class="isotopey">1</li> | |
<li class="isotopey">2</li> | |
<li class="isotopey">3</li> | |
<li class="isotopey">4</li> | |
<li class="isotopey">5</li> | |
<li class="isotopey">6</li> | |
<li class="isotopey">7</li> | |
<li class="isotopey">8</li> | |
<li class="isotopey">9</li> | |
<li class="isotopey">10</li> | |
<li class="isotopey">11</li> | |
<li class="isotopey">12</li> | |
<li class="isotopey">13</li> | |
<li class="isotopey">14</li> | |
<li class="isotopey">15</li> | |
<li class="isotopey">16</li> | |
<li class="isotopey">17</li> | |
<li class="isotopey">18</li> | |
<li class="isotopey">19</li> | |
<li class="isotopey">20</li> | |
<li class="isotopey">21</li> | |
<li class="isotopey">22</li> | |
<li class="isotopey">23</li> | |
<li class="isotopey">24</li> | |
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var list = $('ul'); | |
list.isotope({ | |
transformsEnabled: false | |
, itemSelector: '.isotopey' | |
, onLayout: function() { | |
list.css('overflow', 'visible'); | |
} | |
}); | |
list.sortable({ | |
cursor: 'move' | |
//, tolerance: 'intersection' //'pointer' is too janky | |
, start: function(event, ui) { | |
//add grabbing and moving classes as user has begun | |
//REMOVE isotopey so that isotope does not try to sort our item, | |
//resulting in the item moving around and flickering on 'change' | |
ui.item.addClass('grabbing moving').removeClass('isotopey'); | |
ui.placeholder | |
.addClass('starting') //adding the 'starting' class removes the transitions from the placeholder. | |
//remove 'moving' class because if the user clicks on a tile they just moved, | |
//the placeholder will have 'moving' class and it will mess with the transitions | |
.removeClass('moving') | |
//put placeholder directly below tile. 'starting' class ensures the | |
//placeholder simply appears and does not 'fly' into place | |
.css({ | |
top: ui.originalPosition.top | |
, left: ui.originalPosition.left | |
}) | |
; | |
//reload the items in their current state to override any previous | |
//sorting and to include placeholder, but do NOT call a re-layout | |
list.isotope('reloadItems'); | |
} | |
, change: function(event, ui) { | |
//change only fires when the DOM is changed. the DOM changes when | |
//the placeholder moves up or down in the document order | |
//within the sortable container | |
//remove 'starting' class so that placeholder can now move smoothly | |
//with the interface | |
ui.placeholder.removeClass('starting'); | |
//reload items to include the placeholder's new position in the DOM. | |
//then when you sort, everything around the placeholder moves as | |
//though the item were moving it. | |
list | |
.isotope('reloadItems') | |
.isotope({ sortBy: 'original-order'}) | |
; | |
} | |
, beforeStop: function(event, ui) { | |
//in this event, you still have access to the placeholder. this means | |
//you know exactly where in the DOM you're going to place your element. | |
//place it right next to the placeholder. jQuery UI Sortable removes the | |
//placeholder for you after this event, and actually if you try to remove | |
//it in this step it will throw an error. | |
ui.placeholder.after(ui.item); | |
} | |
, stop: function(event, ui) { | |
//user has chosen their location! remove the 'grabbing' class, but don't | |
//kill the 'moving' class right away. because the 'moving' class is | |
//preventing your item from having transitions, you should keep it on | |
//until isotope is done moving everything around. it will "snap" into place | |
//right where your placeholder was. | |
//also, you must add the 'isotopey' class back to the box so that isotope | |
//will again include your item in its sorting list | |
ui.item.removeClass('grabbing').addClass('isotopey'); | |
//reload the items again so that your item is included in the DOM order | |
//for isotope to do its final sort, which actually won't move anything | |
//but ensure that your item is in the right place | |
list | |
.isotope('reloadItems') | |
.isotope({ sortBy: 'original-order' }, function(){ | |
//finally, after sorting is done, take the 'moving' class off. | |
//doing it here ensures that your item "snaps" and isn't resorted | |
//from its original position. since this happens on callback, | |
//if the user grabbed the tile again before callback is fired, | |
//don't remove the moving class in mid-grab | |
//for some reason in this code pen, the callback isn't firing predictably | |
console.log(ui.item.is('.grabbing')); | |
if (!ui.item.is('.grabbing')) { | |
ui.item.removeClass('moving'); | |
} | |
}) | |
; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "compass"; | |
$charcoal: #6c6c6c; | |
ul { | |
width: 1000px; | |
border: 1px solid black; | |
margin: 10px; | |
} | |
li { | |
width: 100px; | |
height: 100px; | |
background: #ccc; | |
margin: 5px; | |
padding-top: 40px; | |
color: white; | |
font-size: 25px; | |
text-shadow: 0 0 5px $charcoal; | |
box-sizing: border-box; | |
text-align: center; | |
transition: all 500ms ease; | |
transition-property: transform, top, left; | |
&.ui-sortable-placeholder { | |
visibility: visible!important; | |
background: #aaa; | |
box-shadow: inset 0 0 100px $charcoal; | |
&.active { | |
box-shadow: inset 0 0 200px $charcoal; | |
} | |
&.starting { | |
transition-property: none; | |
} | |
} | |
&.grabbing { | |
transform: rotate(3deg); | |
} | |
&.moving { | |
box-shadow: $charcoal 0 0 5px 2px!important; | |
transition: transform 200ms ease; | |
} | |
} | |
/**** Isotope Filtering ****/ | |
.isotope-item { | |
z-index: 2; | |
} | |
.isotope-hidden.isotope-item { | |
pointer-events: none; | |
z-index: 1; | |
} |
@ultimatedelman Thanks man. This works great and it saved my lots of time. Thanks again.
@ultimatedelman ... I have modified your code a bit. What I want is whenever sorting starts I have some conditions and based upon that conditions I will decide if sorting should happen or not.
Please add following code at line number 13 in above fiddle and check errors in the console.
list.sortable ('cancel');
Let me know if you find solution for that. :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ultimatedelman thanks for posting this gist! I created a jsfiddle to demonstrate your code, so that other viewers can see it in action. See here: http://jsfiddle.net/j9S87/