How to swap two draggable elements?
10 MayRecently, on a project, i need to swap two draggable elements from a colum to another. Initially i wanted to use sortables, but i saw that is kinda useless because i don’t have too much control (and same thing happened with other libraries). So i try to make somehow that elements swaps.
Basic HTML markup is this (be careful, i won’t provide any demo for this):
1 2 3 4 5 6 7 8 | <div id="browserCol-01" class="newBrowserCol droppableBox"> <div id="s-5" class="browserDragItem swappable">5</div> </div> <!--/browserCol-01--> <div id="browserCol-02" class="newBrowserCol middle droppableBox"> <div id="s-6" class="browserDragItem swappable">6</div> </div> <!--/browserCol-02--> |
Ok, so we need to swap browserDragItem between each other. Items have two classes because first is to define which elements is draggable and second is to define which element is swapable. I made this way because some elements can be empty (so will not be draggable) but other elements can be dragged over this empty boxes.
Now, if we have basic HTML markup (and i assume that you have css too), we need a function for swapping elements (founded here)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | jQuery.fn.swap = function(b) { b = jQuery(b)[0]; var a = this[0], a2 = a.cloneNode(true), b2 = b.cloneNode(true), stack = this; a.parentNode.replaceChild(b2, a); b.parentNode.replaceChild(a2, b); stack[0] = a2; return this.pushStack( stack ); }; |
Then we put all draggable and droppable on a custom function (for later recall):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function browserDragElements() { $('.browserDragItem').Draggable({ ghosting: true, opacity: 0.5, revert: true }); var newBrowserDrag = { accept : 'browserDragItem', hoverclass : 'browserDragItemHover', onDrop : function(dragged) { var oldDrag = $(this).find('div.swappable'); var newDrag = $(dragged) try{ $(oldDrag).swap(newDrag) }catch(err){}; $('div.droppableBox').DroppableDestroy(); $('div.browserDragItem').DraggableDestroy(); browserDragElements(); } }; $('div.droppableBox').Droppable(newBrowserDrag); };//browserDragElements |
We have try/catch statement because if you drop an element on his initial place, you get some error. All you need to do now is to call browserDragElements() on document load:
1 2 3 | $(document).ready(function(){ browserDragElements(); }); |
I’m not sure that is the best method for doing a “swappable”, but afterall is working well, so we reach our goal, right?
