Share |
Drag and Drop with AJAX Example

by Jamie Munro
Posted on May 27, 2009



At my work it’s quite clear to me that a lot of people have difficulty with both AJAX and drag and drop functionality. In this article, I thought I would provide a realistic and simplistic example of how to accomplish both AJAX and drag and drop together.

By the end of this article you will be able to create an extremely slick content management system that works really smoothly.

The first thing we need to do is create, what I like to call, a “List page”. This page will list our data, in the example below it will list articles and allow you to edit or delete them.

The following code will create our basic table, I’m using static data for this example, in a real CMS system you would have to query a database and loop through and display the results dynamically. Sorry for the formatting, I’m still trying to work out the kinks.


<div id=”content”>
<table class=”listing” width=”550&#8243; border=”0&#8243; cellspacing=”0&#8243; cellpadding=”0&#8243;>
<tr>
<th>Title</th>
<th>Category</th>
<th>Created</th>
<th>Modified</th>
<th class=”actions” colspan=”2&#8243;>Actions</th>
</tr>
<tr class=”dropTarget”>
<td>
<input type=”Hidden” name=”articleid” value=”1&#8243;>
<input type=”Hidden” name=”row” value=”1&#8243;>
Article 1
</td>
<td>Category 1</td>
<td>February 12, 2009</td>
<td>February 14, 2009</td>
<td class=”actions” width=”50&#8243;><a href=”#”>Edit</a></td>
<td class=”actions” width=”50&#8243;><a href=”#” onclick=”return confirm(’Are you sure you wish to delete this article?’)”>Delete</a></td>
</tr>
<tr class=”dropTarget alt”>
<td>
<input type=”Hidden” name=”articleid” value=”2&#8243;>
<input type=”Hidden” name=”row” value=”2&#8243;>
Article 2
</td>
<td>Category 2</td>
<td>February 12, 2009</td>
<td>February 14, 2009</td>
<td class=”actions” width=”50&#8243;><a href=”#”>Edit</a></td>
<td class=”actions” width=”50&#8243;><a href=”#” onclick=”return confirm(’Are you sure you wish to delete this article?’)”>Delete</a></td>
</tr>
<tr class=”dropTarget”>
<td>
<input type=”Hidden” name=”articleid” value=”3&#8243;>
<input type=”Hidden” name=”row” value=”3&#8243;>
Article 3
</td>
<td>Category 3</td>
<td>February 12, 2009</td>
<td>February 14, 2009</td>
<td class=”actions” width=”50&#8243;><a href=”#”>Edit</a></td>
<td class=”actions” width=”50&#8243;><a href=”#” onclick=”return confirm(’Are you sure you wish to delete this article?’)”>Delete</a></td>
</tr>
<tr class=”dropTarget alt”>
<td>
<input type=”Hidden” name=”articleid” value=”4&#8243;>
<input type=”Hidden” name=”row” value=”4&#8243;>
Article 4
</td>
<td>Category 4</td>
<td>February 12, 2009</td>
<td>February 14, 2009</td>
<td class=”actions” width=”50&#8243;><a href=”#”>Edit</a></td>
<td class=”actions” width=”50&#8243;><a href=”#” onclick=”return confirm(’Are you sure you wish to delete this article?’)”>Delete</a></td>
</tr>
</table>
</div>


The two things to understand about our basic table is the <table> tag has a class called “listing” assigned to it and each <tr> (excluding the header) has a class “dropTarget” assigned to it. We will use this in our Javascript code to set up our draggable and droppable elements.

The next step in the process is to begin creating our Javascript code. I will list several snippets below. I have provided a link at the end of this article to download the full source code.


// set up draggable elements
$(”.listing > tbody > tr.dropTarget”).draggable({
appendTo:”body”,
cursor:”pointer”,
cursorAt:{top:20,left:100},
helper:function(){
//this is the drag box that you see when you drag
return $(’<div class=”dragBox”><p>Drag to change the<br/> ordering of this article</p></div>’);
}
});


To accomplish our drag and drop we are using the JQuery libraries, if you are unfamiliar with JQuery you may wish to take a few minutes to read about it. The above code is telling JQuery to turn all <tr>’s with the class “dropTarget” into draggable elements. This simply means it allows us to now drag our table rows around the page. The other options specify how we want some things to look.


return $(’<div class=”dragBox”><p>Drag to change the<br/> ordering of this article</p></div>’);


The above line will create a little box with the message inside it when we start dragging our table row.

Now that we have our draggable elements set up, the next step is to create droppable elements. A droppable elements is an element that waits for a draggable element to be “dropped” in it.


//set up the droppable list elements
$(”.listing > tbody > tr.dropTarget”).droppable({
accept: “.listing > tr.dropTarget”,
hoverClass: ‘droppable-hover’,
tolerance: ‘pointer’,
drop: function(ev, ui) {
alert(’dropped’);
}
});


The above code initializes the same table rows that are draggable elements to also be droppable elements. We have the ability to set a few settings as well. In this example, we tell JQuery to only allow a specific element, set a CSS class when an element is hovered over, and finally we create a function to process the drop. In this simple example it simply does a Javascript alert.

At this stage our example is fully functional and we are able to drag and drop our table rows. The steps are what really makes it slick. We are going to update our drop function to do two new things. The first thing it will do is dynamically move the table row that we dragged to it’s new location and shift all of the other rows up or down. After it has moved the row, we will call our PHP page with the article id and new position. This PHP page will then perform the necessary SQL queries to adjust the order in the database.


var dropEl = this;
var dragEl = $(ui.draggable);

// get article id
var articleId = dragEl.find(”input:hidden”).get(0).value;

// get order
// if they are different, we need to find out if it is above or below
var dropOrder = 0;
// lastObj will contain the element of where we need to insertBefore…
var lastObj;
var rowCount = 0;
var isBefore;
dropOrder = $(dropEl).find(”input:hidden”).get(1).value;

// set the row count that we will be dropping it in
rowCount = $(dropEl).find(”input:hidden”).get(1).value;


The following code does a couple basic things. It initializes several variables, gets the article id of the element dragged, gets the position we dropped it in, etc…


// set lastObj
lastObj = $(dropEl);

if (dragEl.find(”input:hidden”).get(1).value > rowCount)
isBefore = true;
else
isBefore = false;

// insert before lastObj
if (isBefore)
dragEl.insertBefore(lastObj);
else
dragEl.insertAfter(lastObj);


The next set of code set’s lastObj to the object we dropped in. This will be used for us to either insert our dragged row before or after it. We then determine whether we should insert before or after. Now that we determine where it should go, we run the appropriate command. At this point we have now successfully moved the row we dragged.

The second last thing to accomplish is we must reset the row count for all of our items so next time when we drag we know the appropriate position we dropped our table row at. The following code accomplishes this:


// loop through all draggables and update their counts
$(”.listing > tbody > tr.dropTarget”).each(
function(intIndex) {
if (intIndex % 2 == 0) {
$(this).removeClass(”alt”);
} else {
$(this).addClass(”alt”);
}
if (dragEl.find(”input:hidden”).get(0).value != $(this).find(”input:hidden”).get(0).value) {
// adjust the rowcount
if (isBefore) {
// move everything up by 1
if ($(this).find(”input:hidden”).get(1).value >= dropOrder)
$(this).find(”input:hidden”).get(1).value++;
} else {
// move everything down by 1
if ($(this).find(”input:hidden”).get(1).value <= dropOrder)
$(this).find(”input:hidden”).get(1).value–;
}
} else {
$(this).find(”input:hidden”).get(1).value = dropOrder;
}
});


As you can see we also are resetting the “alt” class on every other row. If we don’t do this our alternate rows will no longer be correct.

Finally, the only thing left to do is call our PHP page with AJAX. The PHP page will take two parameters, the article id and the new position.


// set the url of our php page that will accept an articleid and position to update it
var url = “pageThatDoesArticleUpdate.php?articleid=” + articleId + “&position=” + dropOrder;
$.get(url);



I’ll leave you to code the PHP page, but I’ll give you the basics. You should execute three SQL queries. The first query will get the articles original position. The second query will set the new order for the specified article id. The third query should update all of the other articles up or down by 1.

I hope you enjoyed this article, to download the full source code (minus the PHP page), visit my blog for the full source.


I have been developing web sites for over 10 years and 6 years professional. I recently have decided to begin sharing my knowledge through articles and my blog:
http://www.endyourif.com







Print This Article| Send To A Friend| RSS Feeds|Read More Related Articles

COMMENT ON THIS ARTICLE...


First name: Website: (Please include http://)






lost in space writes: Hey the links dont work?

18:08:00 Sun May 31 2009 CDT


The Black Ace writes: Keep em' coming Jamie... thanks!

10:01:49 Fri May 29 2009 CDT


Ajax Links Here writes: Good tip... Computers are suppose to make thing easier to do...

New Languages :In the issues such as caused like Ajax above Even a non-coder should be able to do things like this, with-out even seeing any code :)


3:16:35 Fri May 29 2009 CDT


Shakti writes: Article is useful and informative. Please keep it up giving such decent reading material online.

21:05:45 Thu May 28 2009 CDT


Pages: 1

Follow me    E-mail     Comments (4)

Share     Text    RSS Feed    Print



Post them now in our forums for quick, helpful advice from thousands of members!



Get all the latest webmaster tips and tricks from some of the brightest minds in the online world delivered right to your inbox with the Site-Reference Newsletter

Last name:
First name:


e-mail:


Your privacy is 100% Guaranteed. Easily unsubscribe at any time



Drive traffic to your business and get recognized as an industry leader by sharing your knowledge on Site-Reference. Authors are given a wide range of exclusive benefits here at SR; so checkout what we can offer to those that…



We’re always on the lookout for new writing talent so even if haven’t written for the web yet, feel free to contact us anytime