Dynamic Drag’n Drop With jQuery And PHP
After publishing ScheduledTweets yesterday, I received e-mails asking "how the drag’n drop & saving the new positions to the database was working".
Drag’n drop generally looks hard-to-apply but it is definitely not by using JavaScript frameworks. Here is, how it is done by using jQuery & jQuery UI:
The Database:
We create a simple database as below:

The most important column in the database is recordListingID which shows us the order of the records.
This feature can be applied to any table by adding such a column to it.
The HTML:
We’ll be using an unordered list that is generated from a PHP query that lists the items according to the recordListingID value mentioned above.
Here it is:
</p>
<div id="contentLeft">
<ul>
<li id="recordsArray_<?php echo $row['recordID']; ?>"> </li>
</ul>
</div>
<p>
The JavaScript:
We will be using jQuery UI’s sortable plugin.
<script type="text/javascript">
$(document).ready(function(){
$(function() {
$("#contentLeft ul").sortable({ opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable("serialize") + '&action=updateRecordsListings';
$.post("updateDB.php", order, function(theResponse){
$("#contentRight").html(theResponse);
});
}
});
});
});
</script>
We made the unordered list inside #contentLeft a sortable item, used the serialize function of jQuery to create the array and posted it to updateDB.php.
The PHP:
After posting the array of "new order of the items" to updateDB.php, we must run a query to update our database that will reflect the last positions of every item:
<?php
require("db.php");
$action = $_POST['action'];
$updateRecordsArray = $_POST['recordsArray'];
if ($action == "updateRecordsListings"){
$listingCounter = 1;
foreach ($updateRecordsArray as $recordIDValue) {
$query = "UPDATE records SET recordListingID = " . $listingCounter . " WHERE recordID = " . $recordIDValue;
mysql_query($query) or die('Error, insert query failed');
$listingCounter = $listingCounter + 1;
}
echo '<pre>';
print_r($updateRecordsArray);
echo '</pre>';
echo 'If you refresh the page, you will see that records will stay just as you modified.';
}
?>
You can see that this is the easiest part. We handled the array as $updateRecordsArray and used it inside a for each statement.
With a new variable named $listingCounter, while the for each statement runs, we have updated the values of recordListingID column of every item in the database with $listingCounter values. And that’s it.
- Tags:
Ajax Drag'n Drop jQuery UI Php
- Filed under: Browsing, Goodies, License Free
- 119 Comments
Related Posts



















119 Responses for "Dynamic Drag’n Drop With jQuery And PHP"
Very nice trick, but may I suggest serializing the unordered list items into a string like “1,3,2,4″, and save this one into a separate table ?
This way, you only have to do one query to the mysql server when saving, and one query when retrieving the order, plus you can use the “ORDER BY FIND_IN_SET(recordListingID,’$order’)” where $order will contain “1,3,2,4″.
Thank you for providing this!
I’m looking to use this in part of a photo list reordering admin area for a client. Should fit the bill quickly and perfectly.
Cheers!
@Robert,
I was stuck in-between whether to store them in a single field like you mentioned or to go with the method in the article.
Decided that both can have their advantages in a web app (like getting the order of a single item) & gone with this.
I definitely agree with the amount of queries you mentioned in updates. And had never used FIND_IN_SET. Thanks for that as well
.
@JW,
Great to hear that it will be helpful.
@Umut M.
Well the “store in one field” method is way much better if you have to deal with large sets of data, like for example, a list of products in an online shop, where sometimes, in a category you can have like, let’s say, 50 – 60 products, if not even more. Instead of doing 50 update queries, even if the queries are on an loop, is far much “sane” to just do 2.
On the other hand, the original method is far much better when you have to deal will small sets, where you won’t see the difference between 2 and 10 queries.
One last thing, that I had to take in consideration, and I bumped into it a lot in the last years, is the “childish” behavior of the clients when you handle them such “toys” in the back-end administration, and they play with it all the time
x queries * y arranges due to the client’s indecision/fun = dead mysql server
So basically you have to use the one that fits you and your client best.
Cheers!
Great article, and all of the comments so far are all great as well, especially the on on the users playing..I do agree as well as a second table for order just to save server hits.
@Robert, @KPR,
Totally agree with you. For small amount of records, I’ll store the “order” for every item in the “items” table to reach the “order” faster & store them in an other table for larger amounts of data.
Yes, clients love to play with drag’n drops. And it is great that they generally don’t have Firebug installed, else they could have played more
.
Excellent work, I have been waiting to find something like this. i have seeen methods using the cookie plugin, but never an AJAX request.
Ill make sure to keep this in mind for projects. Im gonna download the code and play around with it.
Ryan
Uh nice. Except the PHP code with SQL string concatenation. Ever heard of escaping (amateur method) or parameterized queries (professional programmers)?
Pretty nice article.
Just a little, question i have, i am having dataset like 30 records which needs drag n drop, so, for each drag drop procedure, i am sending the list through Ajax with backend to update DB positions.
do you think, 30 records are much enough to bottleneck the mysql server , as each drop will have 30 updates statements in loop.??
any suggestion, appreciated
@Dhanu,
It is generally 2 things that bottlenecks database servers: amount of queries + the frequency of them.
If this is a feature at the frontpage of a popular website that everyone can play with, then yes. Else, I’m pretty sure 30 update queries won’t bottleneck a MySQL server.
But if there is a possibility that there may be much more records, then I suggest following Robert’s route.
@Umut M.
So far i am seeing only the cases like 30-35 queries per request, but now i am implementing a check for example, if you have more than 50 or 60 items in list, i will ask user, please remove some elements, to be able to get use of this kool feature of drag n drop …:)
safe our db…
@Robert in comment #1: Robert, you should really read up on thes subject of database normalization and learn that creating compound data like you suggest is a no no. Furthermore, read the MySQL documentation on INSERT INTO table (field1,field2) VALUES (), which takes 1 query and inserts millions of rows in one query. For updating, there is INSERT INTO … ON DUPLICATE KEY variant, which will not insert, but rather update millions of rows in one query.
Hello, i´m wondering if i can put and instead of and ? Is that possible and what part of code should I change? Thanks
Hello, i´m wondering if i can put tr and td (table row) and instead of ul and li (list)? Is that possible and what part of code should I change? Thanks
@Czkoudy,
Although I’m not sure if it will work, it may.
It is hard to explain the parts to be changed in detail but you simply need to change the ul-li codes in the index.php & updateDB.php.
Hello,
Great piece of code!
I’m wondering if there is some way to create new positions with the DB Inserts…
Thanks
@Pedro,
Can you please explain it more?
How to do with multiple columns? Lets say left, mid and right column, how to save to database?
A great little piece of code. It came in very useful when developing a basic portal for showing me how to store the x and y positions! Thanks a lot
thanx, i find what i want.
[...] 7. Drag And Drop [...]
that custom jquery.ui.js is almost 56kb which is very very large for normal sites…
so can any body make a more custom js file for it….?
any body…
removing unnessary parts
I just stumbled across this. I’ll have to give it a try when I get home as I have been wanting to implement something like this on a project I am workiong on.
Hi I just came across this article and plan to use part of it in my music server. I’m searching for a way to make a Drag n drop playlist. Is there anyway to take the item from one DB table and add them to another DB table. Maybe have two list and drag n drop between them, one would be all the available choices and the other would be the finalized list. Any help would be greatly appreciated
@jon,
Although I can guess that it must not be that complicated, I have never moved objects between 2 lists and don’t know the limits there.
I have used jQuery Sortable in this article & you may want to check the features of it here: http://docs.jquery.com/UI/Sortable which might give an opinion about the answer.
And, if you manage to do it, would be great if you share your experiences here. Bests.
very nice, gr8
Is there any way to replace an item in the list rather that reordering it. ie replace 1 with 4
Great article by the way, I’v been having a good play and can see a lot of possibilities
[...] web: http://www.webresourcesdepot.com/dynamic-dragn-drop-with-jquery-and-php [...]
Thank you very much for this tutorial, I am now playing with incorporating it into my admin interface. One problem I’ve stumbled on is utilizing multiple instances. I am using a combination of JQuery’s accordion and this, with the accordion instances displaying the names of my categories, and then when you click on it, it opens to display the list of products in that category, which I want to be sortable. I can easily pass category names by appending them to the array ([0] => 48.8) and then processing with php, but not being very familiar with Javascript, I am having trouble with passing more parameters to the function itself, such as the names of the div to sort? (contentLeft_1, ontentLeft_2, and so on)? Thanks!
@Paul,
If I didn’t get the question wrong, I believe you can do that on the query side. But as far as I know “sortable” doesn’t support a replacing effect so you may need to do that on the server-side & may be update the look (Ajaxed) to reflect the replaced version.
@Mike,
I have just checked the serialize event again but seems like you can’t send 2 different arrays.
You may go with a trick and create the array name like catName_Cat1-recordsArray_1 and use toArray (http://www.jqueryui.com/demos/sortable/#method-toArray) & create a function on the PHP side to split the contents and run the query accordingly (what I wrote may be totally wrong but looked logical to me
).
@Umut M.
I may have expressed my idea wrong – I don’t really need to send two arrays to php simultaneously. What I am trying to achieve is to pass a parameter to the Javascript function so I can have several instances of “contentLeft” div’s on the same page. It works just fine, however, only the first instance really works. I am sitting here thinking of how to trick it, but my Javascript skills are below average to say the least
In essense, I am thinking of making unique div names with PHP (thus, each sortable is in its own uniquely identified DIV) and then pointing the main function to the correct div when it is being sorted, so the part of the function with $(“#contentLeft ul”).sortable … is replaced with $(“#contentLeft_1 ul”).sortable, $(“#contentLeft_2 ul”).sortable and so forth.. I just don’t know how to pass this sort of parameter to it… Sorry for the confusion here, I am not a native english speaker… Let me know if any more clarification is needed, and I’ll upload what I got so far somewhere.
@Mike,
Hmm, got it.
You can create a function which does the following:
Once an user clicks inside an accordion level, it reaches to the parent elements id (category in your case) with jQuery’s “parent” selector & creates a custom function with that value like: $(“#contentLeft” + customValue + “ul”).sortable)…
I may be missing something here but can see that if you’re not that familiar with JS, this may be a headache to create.
If you won’t have too many accordion levels, you can create js functions for each level like:
$(“#contentLeft1 ul”).sortable…
$(“#contentLeft2 ul”).sortable…
$(“#contentLeft3 ul”).sortable…
…
& it will work, although it won’t be the best coding pattern.
Thanks, I think I see what you mean. I’ve thought of creating multiple functions, just don’t like the idea of something less than perfect
I might settle for it for now, but ideally, I think I’d love to try your approach with the parent call (once I know what that is). I imagine many people out there might have this problem, plus, I foresee myself utilizing the same for other sections of my site, where there might be many more categories, so a universal function would still come in handy. Here’s what I got so far, simplified (just the output, no database there, but hopefully gives you the idea…) http://stereo80s.com/jdd/index.html
Thanks!
Would really appreciate a quick and dirty solution
Oh, just thought that they don’t even have to click on the accordion level, what if it was triggered by them clicking inside the sortable instance itself? Then it’d be like the ultimate sortable plugin with unlimited uses!
Hello
First I say thank for you for writing this great tutorial.
Using your source code I apply on my structure but one problem is coming.
I want I use your tutorial for simple html without using their table or using separate table in which simple recordID and recordListingID is it possible? Actually on which structure I want to apply your tutorial this data structure(on which structure i apply drag and draw ) is coming from different tables. Is it possible
This is realy Such a nice thing to shareeeeee . Great sharing
thank you very much. good job…
sorry if its duplicated but i typed a wrong e-mail address
hello,
i have managed to get a list from an XML file, but i m having problem updating the listing in the xml file! any help plz.
thanks
youppi, i did it myself:D:D
i can now load data from xml files and able to reorder them changing nodes…
its just great:D
thanks
@ziad,
Great to hear that. Congrats
very good but not working on firefox 3
It’s working just fine on Firefox 3. Turn on javascript…
This is the best drag and drop explanation by far – thanks!
I am still reading about drag’n drop with jquery, but till now your explanation is one of the best.
http://www.dhtmlgoodies.com/scripts/drag-drop-nodes/drag-drop-nodes-demo3.html
Umut – I have been trying to get similar functionality as shown in the link above – but not able to follow how to send the info to a MySQL table.
I would like to have the following :
1 – 1 list of items to drag
2 – 2 containers to drag them to
3 – Once each item has been dragged over to each list – the item goes away
4 – Once this is complete – have the option to write each of the 2 containers into tables
Any ideas?
Again – great tutorial to get me started with jQuery!
Hi,
is there anyway to make some items on the list not movable?
thanks
I have tried your code and it is working fine for the first drag and drop action. After that it is not working. I tried with get method than post and what i saw is after the first action, the ” recordsArray ” value is not passing, it seems as undefined. Can some one help me on this issue
Thanks
I kept the php code in the middle of the file and so in the jQuery Ajax response, the whole file content are retrieving and because of that the code was not worked as I mentioned in my previous comment. I tried now by kept my php code at the top most of the page and so it is working fine now
Thanks
akhi
@Akhil,
Is this the demo that you’re having the problem or a local installation (are u having the problem with the demo)?
@ Umut M
I tried it in localhost and it is working fine now as i updated the code as i mentioned in my last comment.
Thanks for your quick reply
@Akhil,
Great to hear that. If not using Firebug, definitely suggest it as it can show the responses better to quickly analyze such problems.
Bests.
Hello
Thanx for your code it’s works fine. I have a question : Is it possible to refresh the drag and drap sorting list (div contentLeft in the example) with ajax. I try to make a simple document.getElementById(‘contentLeft’).innerHTML=. Display is good but drag and drop doesn’t works. Anybody has an idea ?
Bests.
Gary, I have the same problem like you
[...] Dynamic Drag’n Drop With jQuery And PHP ↓ [...]
Good Work.!!
i’m not download code!
este es un plugin para jquery facil de usar jQPOOOP y carga por ajax y texto simple que enconte el otro dia
http://www.dieroboter.com/jQPOOOP
or
http://code.google.com/p/pluginjquery
Hi everybody,
Please if any one of you guys, knows, such an example with flash please let me know which is dealing with flash and php I’ll be very very grateful to you.
Thanks
[...] bir ay önce ASP ile yapılmış bir sürükle-bırak uygulaması arıyordum ve PHP ile yapılmış şu örneği gördüm. Bu sistemdeki PHP kodlarını ASP’ye çevirdim ve ortaya işime yarar [...]
i tried making my list from left to right, but the script breaks when I do it. any suggestions?
@hitek,
I can’t see any reason as it is the list that matters rather than how it is styled.
I suggest that checking jQuery’s sortable if there is anything special with horizontal lists.
I tried this code for drag and rearrange page numbers.I have In one container 2 page no’s..Hence I recode ajax page for updating database.. I used div tag instead of li tag.Its working in internet explorer 6.0 only. Mozilla, safari chrome didn’t work.No request gone when dropping the pages.Any suggessions plz..
Hi friends,
I used the div tag for displaying the list from left to right, So I gave div style as style float:left; So the when i drag it comes there itself..No request gone because of this stlyle float left..Any Suggession for breaking float left
@asma,
“floats” can be problematic w,th interaction.
For a horizontal list, if you try a CSS like: http://css.maxdesign.com.au/listamatic/horizontal01.htm I believe you may have a better chance to make it work.
Hi,
I tried this style.It is working the li tag contains text..In my Li tag contains set of div tags..Any possibility to display Set of divs in horizontal direction without using float:left and position absolute
cok cok teşekkürler arkadasım
hi, very very thank you good job…
Thanks works fine
Just what i neded!
Thanks, saved me a lot of time. Works Great.
I’m developing a card game for a child cancer research study and this is the closest thing I’ve found to what I need. Thank you so much. The question I have is how to go about having the list items, rather than being resorted, be dragged into 5 multiple choice positions. There are 110 question cards the child is asked to place in 5 positions from Never to Always. Any help would be much appreciated.
@Nick,
I think starting from this example would be wrong for your needs.
You can easily accomplish what you’re looking for with the jQuery UI’s droppable. Take a look at the examples here: http://www.jqueryui.com/demos/droppable/#default
It is highly customizable and well documented. Hope it helps.
Umut, Thanks. Yes, I’ve used that site to get the where I am so far with the project, which is everything but sending the location of all of the dragged cards to a record within the db. There is a deck position they start of stacked in, a choose not to answer position, and then the Never, Rarely, Sometimes, Often, Always positions. I’m sorry if this is off topic; the part of this code here that I liked is the AJAX that sent the position of the dragged object to the db, also that it generated the objects from a db; I’ll definitely use those. It’s the object buckets, so to speak, that is the main challenge. Thanks again.
Fantastic tutorial, top notch and very easy to implement. This has really opened up the door to me for how easy it is to do behind the scenes updating using php/mysql! Thanks!
This is really a fantastic tutorial and very easy to use.
Thanks for sharing this helpful PHP tutorial with us….I am ready to use for my website.
Thanks one again
Great article, just wondering if it would be possible to easily combine this with input fields as well?
The code works great when I use unordered lists. I just tried it on code that had tags and it won’t work. Can I not drag/drop p tags?
Thanks!
Very nice! I’m using this on my custom homepage to help enhance the link dock.
Hi Robert I need :$ a little help if you could help me or anyone that could help me anyway, I am making a web application and now I used this drag and drop tool just the same but the matter is that the storing procedure should run after the user clicks on the buton Save the list.
I tried in many ways but the order value of javascript isn’t appearing to me I tried to make a session with its value and when user clicks save I tried to update that session to database but the value of that kind that javascript makes php can’t face it or I don’t know how to end this.
@Mentor Gashi,
You can call the serialize function when you click the “save button”.
The code below:
var order = $(this).sortable(“serialize”) + ‘&action=updateRecordsListings’;
$.post(“updateDB.php”, order, function(theResponse){
$(“#contentRight”).html(theResponse);
});
is triggered when the drop is completed. You must remove it from there and add it to your save button’s “click” event.
Hope it helps.
@ Umut M.
Thanks a lot for your reply Umut, but I tried as you said but didn’t work because when you take this code:
var order = $(this).sortable(”serialize”) + ‘&action=updateRecordsListings’;
$.post(”updateDB.php”, order, function(theResponse){
$(”#contentRight”).html(theResponse);
});
out from that function part it doesn’t know what value does have this $(this).sortable and what to serialize.
@Mento Gashi,
You’re right with that. Although haven’t tried, using the id or class of the
rather than “$(this)” may work like:
$(“#id-of-the-div”).sortable…
If it doesn’t work, I suggest you check the jQuery UI documentation for that, must be something close..
Thanks a lot for your help
I made it using cookie
(TSK UMUT)
this is helpful, im lovin it!
Hi,
Great script, thanks a lot !!!
I have some data stored in each ,and problem appears on tablet pc, as I cant click on links. Is it possible to dissable draging when you click on link in
Can i use a instead of a ?
e.g.
Coz most data is putted in tables
Hey,
I’m trying to apply this to my code and I can’t seem to be able to apply this to tables and inner div. (I have changed the $(“#contentLeft ul”) to $(“#contentLeft div”), $(“#contentLeft table”) and it doesn’t help)
I’m trying to add the ability to sort images on my gallery pages.
The images along with their (delete, show/hide) links are in a div that contains a table. And while it does allow me to drag it won’t make space for it nor will it allow me to drop for resorting. This only seems to be working with lists (ul, li) is there a way to make this work with divs and inner tables.
Any ideas?
Thanks,
David
@David,
I’m not sure if tables are supported to be drag’n dropped by jQuery UI, never tried it.
I suggest that you check the jQuery UI docs for that.
I may have missed it in the documentation/comments, but is there a way to make a value of the array non-draggable?
I would like to use this for clients to arrange records, but I would like to control which ones they can and cannot arrange depending on certain variables.
Hi!
Thank a lot for the script!
I´m just playing around and have a question:
How do I modify the function, if I want to transfer another variable?
The tablename “records” should be variable. I have modified the MySQL-Statement in updateDB.php, “catch” it with “$table = $_POST['tab'];… But what do I have to do, to get the variable “tab” in the Poststring?
(At the end, I want to create various tables…)
I´m sure it´s a pretty simple solution.
The question above is also very interesting.
(…and sorry for my poor English.)
Best wishes
DD
Hi! Thanks for a great post! I’m just curious; how come you wrap it all inside a function() in the document.ready()?
Hello everyone,
Is there a way to assign a value from my database to the array key instead of it auto-incrementing from 0?
I suspect it’s something to do with the JavaScript.
I’m a student and am implementing this script into a project. Any help would be appreciated.
Thank you!
Thanks, Thanks for the script
Great Article, however you’re update script is vulnerable to sql injection…
mysql_real_escape_string($_POST['action']);
with magical quotes phasing out this is critical…
@Pete,
Thanks very much for that. Just updated it.
Very nice, Thanks.
I am attempting to use this more than once on a page, so for 2 different lists. The first list will work, but the second will not. If I remove the first, then the second will work. The I modified the jquery so that it is different enough, at least I thought I did. Any advice on how to get this to work for more than one list on a page?
Nevermind. It seems to work now. Not exactly sure what the issue was.
Hi,
I wonder how could I modify the “onmove” javascript at start to send to the server side php just the released position.
EG:
I move element 8 to position 3, I want to send to my php, only the number 3.
Anybody can help with this ?
I have been trying this for hours and it will not update the database. Did anyone else have this issue with the downloaded code?
Hi Umut M! Nice tutorial! Thanks alot! Tell me please can I use it in commercial theme or plugin?
@Den,
Yes, sure. Go ahead (and hit the jackpot)
.
Thanks, there are many tutorials on this method, but this is the one that works. Easily downloadable ZIP with all necessary files, including an SQL query to create the database. People should always do tutorials like this.
Hey, thanks using this was a snap after hours lost in trying to find a simple and efficient list ordering solution. One question though, how can you possibly get it to work with pagination/paginated data say for instance you are dynamically generating the list from a table with 30 list items and you paginate with 10 per page and you are trying to:
1. retain the overall order but change the order of the ten items in view (i.e. working on 2nd page with list items 11-20 reorder just that without influencing the rest of the pages){one way – get position of the first list item from db and equate to $listingCounter, is there a better way? }.
2. reorder list items across the pages i.e. list item 12 in page 2 to move to list item 3 in page 1{possible solution but unable to work it out: move list item to top/bottom of page and have a link to move it up/down which swaps it with the last/first item on the previous/next page}.
Any ideas would be greatly appreciated.
Note: Pagination would also reduce the number of queries run.
Eric,
Seems like you’ll have to make a custom trick there:
1.
- Let’s say you’re on page 2 where the recordListingID starts with 11.
- Make this 11 a variable in PHP.
- After the drag’n drop there will be an array from 1-10. You’ll have to update your recordListingIDs with 11+array (and maybe -1, depending on how you shape it).
- To sum up, you only need to know where your recordListingID starts in that specific, paginated page.
2.This will go beyond tricky but if you like digging the code and cracking keyboards, you can combine this demo with http://www.webresourcesdepot.com/load-content-while-scrolling-with-jquery/ which can end in something awesome.
Thanks a lot Umut, for the script and reply. Will definitely check it out, try it, post back and give credit on success.
thank you
any success eric ?
i’m trying to do exactly the same thing. thanks
i want to know if we will use an form and what is the parameteres to put in action and method???
Great code – worked nicely with my product categories.
How would this work if I had nested lists?
So 4 levels of categories?
hey, thanks a lot, great article
!
[...] 10. Drag’n Drop With jQuery And PHP [...]
I agree with Zmip in that a single INSERT query to update all order id’s is better in any case than a single query per row or Robert’s idea to serialize in one field.
A single query can be used like:
INSERT INTO
table (recordID, recordText, recordListingID )
VALUES
( $recordID1, ”, $recordListingID1 ),
( $recordID2, ”, $recordListingID2 ),
…
ON DUPLICATE KEY
UPDATE recordListingID = VALUES( recordListingID );
and as long as recordID is a unique key, it will update all recordListingIDs in one query.
Cheers
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Hi, very nice ,
It’s possible to do the samething in java jsp ?
thanks
Great tutorial, Thanks
Hi, thanks a lot. Save my a lot time.. !!!
Thanks for this wonderful script..
I’m trying this system with c #. But ['recordsArray'] is empty, constantly sending. A definition that does not exist in code recordsArray .. I could not understand the rate?