How to swap two draggable elements?

10 May

Recently, 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? :P

Tags: ,

Bookmark this article!

Del.icio.usDiggStumbleUponFurlRedditTechnorati

SlashDotWindows LiveYahooGoogleFacebookBlogLines

5 Comments »

  1. [...] wrote here how to make two elements to swap each other. But one little problem remain unsolved: you swap [...]

  2. May 20, 2008 Zefyrus said:

    Hi

    What was the jQuery and jQueryUI version used?

    with the latest code nothing works; i made some basic changes but I got an javascript error on $(’div.browserDragItem’).draggable(”destroy”);.
    if I try catch the action it works good on FF but IE crashes: element error.

    here is the updated code:

    function browserDragElements() {
    $(’.browserDragItem’).draggable({
    ghosting: true,
    helper: ‘original’,
    opacity: 0.5,
    revert: true
    });

    $(’div.droppableBox’).droppable({
    accept : ‘.browserDragItem’,
    hoverclass : ‘browserDragItemHover’,
    tolerance: “touch”,
    drop : function(e, ui) {
    var oldDrag = $(this).find(’div.swappable’);
    var newDrag = $(ui.draggable);
    $(oldDrag).swap(newDrag)
    $(’div.droppableBox’).droppable(”destroy”);
    try{
    $(’div.browserDragItem’).draggable(”destroy”);
    }catch(err){};

    redoD();
    }
    });
    };//browserDragElements

  3. May 20, 2008 Ionut Staicu said:

    Hello Zefyrus.
    As you can see, my code is for Interface (1.2) and jQuery 1.1.2 (the last version of jQuery that work with interface is 1.1.3, but i’m not sure is 100% functional).
    Unfortunately i didn’t use UI until now so i don’t know what to say. but basically is the same thing (onDrag you check the id of droppable and you replace with draggable element; after that, you swap elements). tell me if you have any luck with that and if not, i will make you a short example ;)

  4. May 20, 2008 Zefyrus said:

    Hi again
    I found the problem, i was using jQueryUI not Inerface for jQuery! that`s why a part of the code was completely wrong. Sorry.
    BTW - the code works perfectly!

  5. May 20, 2008 Ionut Staicu said:

    Great then :D
    I was glad to help you. If you need anything else, please let me know ;)

Leave a comment