Simple Draggable Element Persistence with jQuery
At some point you may need to create a draggable element within your web application. This is great functionality, however you may want or find that you need the element to stay in place after being dragged around. In this tutorial I will show you how to easily drag an element and make it stick, even after a page reload, by grabbing and storing its X and Y coordinates.
Scenario
So you have an element in your web application. You can drag it around, put it here and put it there. But, when the page is reloaded in any way, the element returns to its default position. While you want the element to be draggable, you don’t want it to move after its been dragged. Let’s look at a simple solution to give us this ability.
Getting Started
For this tutorial we are going to need the jQuery library, jQuery UI, and the jQuery-JSON plugin by Brantley Harris. We will also be using some PHP and a MySQL database to parse and store our data. If your new to jQuery, no worries. jQuery is a highly extensible, fast, and lightweight JavaScript library which is both fun and easy to use. The library has very nicely structured documentation, and a huge community. This is my first tutorial on jQuery and JavaScript, so please bear with me. I hope to explain everything as best as I can and if you have any questions, please feel free to ask.

The HTML amd CSS
I wanted to start off with the HTML and styling for this tutorial since the effect is applyed to HTML elements, it helps to visualize what we are going to do, right off the bat. First the CSS:
html, body {
background:#151515;
margin:0 0 0 0;
padding:0 0 0 0;
}
#glassbox {
background:#333;
border:1px solid #000;
height:400px;
margin:30px auto auto auto;
position:relative;
width:960px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
#element {
background:#666;
border:1px #000 solid;
cursor:move;
height:143px;
padding:10px 10px 10px 10px;
width:202px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
#respond{
color:#fff;
margin:0 auto 0 auto;
width:960px;
}
The CSS is very simple. We set the html and body properties to clear margins and padding, and continue by setting some heights, widths, and other properties to our elements so it doesn’t look so bland. -moz-border-radius and -webkit-border-radius are two properties which allow us to create rounded borders (applicable only to Mozilla Firefox and Safari 3 at the moment) for our elements. Let’s take a look at the HTML:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Simple Draggable Element Persistence with jQuery</title> <link rel="stylesheet" href="style.css" type="text/css" /> <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script> <script type="text/javascript" src="js/jquery.json-2.2.min.js"></script> </head> <body> <div id="glassbox"> <div id="element"><img src="nettuts.jpg" alt="Nettuts+" />Move the Box<p></p></div> </div> <div id="respond"></div>
As you can see we just setup a very nice and simple page which calls in our CSS, JavaScript library and plugins, and contains the elements which we will be using to apply some effects and events to. As a note,the jquery-ui file is a custom build which only includes the core and the draggable interaction functionality.

The Javascript
Now for some juicy interaction! Lets first take a look at some of the basic functions we will be using to apply some effects to our elements. Let’s tear it down.
<script type="text/javascript">
$(document).ready(function() {
$("#element").draggable({
containment: '#glassbox',
scroll: false
})
First we tell the browser, “Hey, this is some code we want to run; it’s not HTML, it’s JavaScript.” We then want to wait for the document to load before we do anything else, once thats happened, we call a function to select our #element DIV, and add the draggable handler with some basic options. The containment options will keep our element within the parent DIV, and we set scroll to false because we don’t want any scrolling to happen. Let’s move on:
.mousemove(function(){
var coord = $(this).position();
$("p:last").text( "left: " + coord.left + ", top: " + coord.top );
})
With this tidbit, we call the event handler mousemove and tell it, “When the mouse moves, set the variable ‘coord’ to equal our selected #element’s position.” Then we select a paragraph (“p:last”), the last one in #element, and print some text which will read out the left(x) and the top(y) properties of our element relative to the parent object (which is #glassbox).
.mouseup(function(){
var coords=[];
var coord = $(this).position();
var item={ coordTop: coord.left, coordLeft: coord.top };
coords.push(item);
var order = { coords: coords };
$.post('updatecoords.php', 'data='+$.toJSON(order), function(response){
if(response=="success")
$("#respond").html('<div class="success">X and Y Coordinates Saved!</div>').hide().fadeIn(1000);
setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000);
});
});
});
</script>
Ok now for some devilry! In this snippet we are going to do a couple of things. First we want to setup an empty array, and then get some values to fill it with. By calling the event handler .mouseup() we are telling the browser to look for the event when you unclick your mouse. We set the variable coords to equal our empty array, and again set the variable coord to equal the position handler of our #element. Then we need to create a list of items, these will be coordTop: and coordLeft: respectfully equaling our #element’s left and top positions. With coords.push(item) we are literally pushing our item list and filling the coords array with it. Then set the variable order as a new list where the coords key will equal our coords array. Now for some AJAX.

$.post is an AJAX request handler which loads a remote page using an HTTP POST method. This function looks for the parameters: url, data, callback and data type to be returned. In this tutorial we specify the updatecoords.php file as our URL because this is where we want to send our post data, we then define our datatype by including the $.toJSON function defined in our jquery-JSON plugin and setting our variable order as the data to be handled by .toJSON. Next we create a callback which checks for a return response from our PHP file upon success, and add a bit of flavor by saying, “If whats returned is equal to success then…” We keep this html hidden by using the effect handler .hide, and tell it to fade in at 1000 milliseconds, wait with a timeout for 2000 milliseconds, and tell it to fade out again. In the end our JavaScript should look like this:
<script type="text/javascript">
$(document).ready(function() {
$("#element").draggable({
containment: '#glassbox',
scroll: false
}).mousemove(function(){
var coord = $(this).position();
$("p:last").text( "left: " + coord.left + ", top: " + coord.top );
}).mouseup(function(){
var coords=[];
var coord = $(this).position();
var item={ coordTop: coord.left, coordLeft: coord.top };
coords.push(item);
var order = { coords: coords };
$.post('updatecoords.php', 'data='+$.toJSON(order), function(response){
if(response=="success")
$("#respond").html('<div class="success">X and Y Coordinates Saved!</div>').hide().fadeIn(1000);
setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000);
});
});
});
</script>
Place the JavaScript below the HTML, right after the closing body tag.
The PHP
Alright, now lets get to business on doing something with the data being posted from our jQuery. First lets create a simple database to store our coordinates, which we will then later retrieve to define the position of our element. Second will be our config.php file which will store our database connection settings, and then we will finish with updatecords.php.
Database: 'xycoords' CREATE TABLE IF NOT EXISTS `coords` ( `id` int(11) NOT NULL AUTO_INCREMENT, `x_pos` int(4) NOT NULL, `y_pos` int(4) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
config.php
<?php
/*Database Settings*/
$db_host ="localhost"; //this will likely stay the same
$db_name = "xycoords"; //name of the database we will be using
$db_usr = "database_username"; //db username
$db_pass = "database_password"; //db password
//Connect to the database
$link = mysqli_connect($db_host, $db_usr, $db_pass) or die("MySQL Error: " . mysqli_error());
//Select our database
mysqli_select_db($link, $db_name) or die("MySQL Error: " . mysqli_error());
?>
updatecoords.php
<?php
if(!$_POST["data"]){
echo "Nothing Sent";
exit;
}
include ('config.php');
//decode JSON data received from AJAX POST request
$data = json_decode($_POST["data"]);
foreach($data->coords as $item) {
//Extract X number for panel
$coord_X = preg_replace('/[^\d\s]/', '', $item->coordTop);
//Extract Y number for panel
$coord_Y = preg_replace('/[^\d\s]/', '', $item->coordLeft);
//escape our values - as good practice
$x_coord = mysqli_real_escape_string($link, $coord_X);
$y_coord = mysqli_real_escape_string($link, $coord_Y);
//Setup our Query
$sql = "UPDATE coords SET x_pos = '$x_coord', y_pos = '$y_coord'";
//Execute our Query
mysqli_query($link, $sql) or die("Error updating Coords :".mysqli_error());
}
//Return Success
echo "success";
?>
This is pretty simple to follow. The first thing we want to do is check to make sure our post data is being passed to the file. If that happens we include our config file for our database connection and set the variable $data to json_decode(passed post variable); json_decode is a PHP function implemented in PHP 5.2.0 which allows us to decode a JSON string.
Since our $data variable contains an array of data, we need to tear it apart to get the values we need. To do this we take foreach $data->coords (which is from our order variable in our JavaScript) as an item. This takes each key and value pair and creates an item object from the array, we then specify and create a variable out of it. We use this in conjunction with preg_replace so that we can take out the characters we don’t need. We then, as good practice and a measure of security, escape our values to prepare them for insertion into the database. If all goes well, we need to return success to our JavaScript to let it know everything went just fine.

Lastly
Now that we have what we need in place, to grab the position coordinates from our element and pass it to PHP for storing, we need to modify our HTML to reflect the position of our element. To do this we change the basic element HTML and instead create it with PHP:
<div id="glassbox">
<?php
//Create a query to fetch our values from the database
$get_coords = mysqli_query($link, "SELECT * FROM coords");
//We then set variables from the * array that is fetched from the database
while($row = mysqli_fetch_array($get_coords)) {
$x = $row['x_pos'];
$y = $row['y_pos'];
//then echo our div element with CSS properties to set the left(x) and top(y) values of the element
echo '<div id="element" style="left:'.$x.'px; top:'.$y.'px;"><img src="nettuts.jpg" alt="Nettuts+" />Move the Box<p></p></div>';
}
?>
</div>
<div id="respond"></div>
Here we setup a basic query to the database to select all the rows from the table coords. We then invoke a while loop which specifies each row we select as $row. Now we can set some variables to equal each individual row we pull from the database, and echo them in the proper place within the elements style (left and top).
Wrapping up
Well I hope that you enjoyed this tutorial as much as I did writing it! It may not be perfect. While this is just one way to get this functionality in a draggable element, there are other ways (and perhaps better) to achieve it. Once such way could be to store the coordinate values in a cookie, to keep calls to the database at a minimum. You could also serialize the values passed from jQuery to PHP instead of using JSON. This tutorial is just one example from which you can expand upon. Thanks for reading!
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web.







Wow, 1st one to get to comment.
This looks like just the thing I’ve been looking for!
Thanks for a great tut!
omf when does this stupid “look how cool i’am because i’am first” thing stops
Never ever! Now I am the third!
oh mate. its rediculous.
Fifth, Yes!
Sixth, Yes!
.
There are a few bugs in this tutorial and could be made much better if it was coded well
Cool tut.
Demo
I agree, a Demo would be nice.
Although, if they had a demo, it wouldn’t be the same if you changed it, someone else visited the page and changed it, and you refreshed.
Just remove the mysql part from the demo and have it start at a default position every time.
This isn’t very intelligent xD Think about it!
@Jason – Right , you would need it to be used in a ‘per person’ form such as in a user table, or in a cookie to ensure the element position is unique to each individual.
I agree with Cory.
When you drag the element around you can show the JSON sent to the server in an alert box.
Demo -> http://www.onlinefacil.com.br/arrastar/savestate.php
I also made some improvements to work with multiple elements, as it makes sense to have a table for a single record.
Marcelo, theres a “bug”. If you hold one of the elements and move it to one side of the parent element, hold the draged element and move the mousepointer out of the parent element, the position of the draged element wouldn’t be saved.
This should be fixed.
need demo!!!
Very cool and become handy
Nice tut. Enjoyed reading it.
in the mouseup function, I think you meant to say:
var item={ coordTop: coord.top, coordLeft: coord.left };
not:
var item={ coordTop: coord.left, coordLeft: coord.top };
Very slick. Will definitely use this.
Thank you very much for this Dustin, it is very helpful, i wonder if i could apply this to my CodeIgniter project, i am building small CMS HTML editor for my company, but didn’t have any idea how to position some elements in parts of the website. If i had 3 parts website with header, main and footer and in the header div i have logo image, could i use this method to position the logo in the header section and write its new position to the database, so when i produce the layout i will read it from the database. I know it is kind of lame to do such thing, but company wants it and i want to do it
.
Thanks again
Hey there!
Nice tut. But think about that:
User X moves it around, it gets saved in the DB.
In this moment user Y reloads the box and the div is on a completely different position!
Either you should go with … well saving it to the DB along with the IP or you’d have to go with Cookies which in my opinion would be the better oppinion. Like a cookie for a year or so…
Lots of work for something that’s supposed to be “simple”. But still cool
Was surprised to see PHP and mySQL… Isn’t this supposed to be the kind of thing you store in a cookie?
Whether it’s in a cookie or server side definitely depends on the situation you’re using it for.
But still, my mental statistics tell me most draggable stuff needs to be in cookies. I’m thinking draggable interface elements (menus, modal windows or option boxes). Those would have no place anywhere else than on the client side.
Hmm… if you had a puzzle game for maybe with draggable pieces, now that would need to go on the server.
Uh. Or that game where you have play dress up with a doll.
Should go in a cookie 90%+ of cases.
From the last section ‘Wrapping up’:
“While this is just one way to get this functionality in a draggable element, there are other ways (and perhaps better) to achieve it. Once such way could be to store the coordinate values in a cookie”
Right, you do mention that!
I read all the comments before posting mine to see if anyone else said the same thing, but I skipped the end of the article
My bad.
Another option would be to store the coordinates in a cookie instead of the db. It totally depends on why you want the user to be able to drag stuff around. Also, it would be better to use the draggable events rather than mousemove/mouseup. Doing that could simplify your event processing. Good first article.
Right,cookies are another good option, and may suite many more needs. You have to consider how much persistence you want. Cookies are only as persistent as the user allows them to live or what their time to live is set to.
Woow. It Cool!
I tried it by the source given . there is some bug in the source it is only dragging but not saving the position in the database table ..
Help me out ..
That doesnt help solve your problem, could you please be more specific?
yes i solved
actually need to stip the slashes in the post request
chenged the line to from the file updatecoords.php
$data = json_decode($_POST['data']);
$data = json_decode(stripcslashes($_POST['data']));
Now it works fine
How would I make it so I have multiple draggable divs?
Hi really a nice tutorial..
but i think there is no need to convert data in json.
i am sending like this-
$.post(‘updatecoords.php’, ‘data=’+coord.left+’||’+coord.top, function…
and at updatecoords.php simply –
$cords = explode(‘||’,$_POST["data"]);
$sql = “UPDATE coords SET x_pos = ‘”.$cords[0].”‘, y_pos = ‘”.$cords[1].”‘”;
//Execute Query
mysql_query($sql,$link) or die(“Error updating Coords :”.mysql_error());
echo “success”;
Where is the demo????
This is really cool! May use this for a flow chart editor I need. Or would you know of any JQuery extension that does flow charting out of the box?
Thanks for your contribution!
ok.. nice tut,
but where is the Demo???
Brilliant tutorial. Can be implemented with several projects ideas.
Nice tutorial. Makes me think about how browser storage in the more recent versions of Safari et al could pull this kind of personalisation out into the user’s environment and off the server.
very nice but whree is the demo?
a powerful code that inspire me something
Can someone explain to me why the use of the json plugin… I’m new to jquery but arent’ you allowed to pass json variables in with your .post anyways?? eg $.post(‘updatecoords.php’, {cordx : cordx, cordy : cordy }…
Dusin or someone else please explain… Thanks
How am I suppose to run this, I mean, it says $_POST but what the hell am I posting???
Nice, cool article – I”m with esranull and Monie -> wheres the demo?
If it does not work replace
$data = json_decode($_POST['data']);
with
$data = json_decode(stripcslashes($_POST['data']));
as Anand Kumar pointed out
Very nice tutorial!
@Marcelo: thank you for your demo, great job!
( Demo -> http://www.onlinefacil.com.br/arrastar/savestate.php )
Good tutorial, it can be well adapted into templates.
I like it. I think I might learn this by following each step, maybe it will help in some of my projects
.
Btw, “The HTML amd CSS” ? I think it should be “and” not “amd”…
“if your new to jquery”
*hiss* huge pet peeve of mine.
can’t expect everyone to be well versed in it or JavaScript
Who cares for dragable items on webpages (and to remember by browser what was dropped into another page layout-place)? It is totally unuseful – only good stuff for demonstration (nice looking functionality, but totally not wanted for real web usage – and it requires not only JS and PHP but also DataBase(!)). I do not care for Java Script. I have it disabled in browsers. I was also making great looking ads in JS, but in fact they where always just only ads for users. They need useful and good writen text content only (and only, not just another web page with not intuitive navigation and non-clean optionality). By the way: why can’t author use cookie or cache functionality of html5 (instead of enabling all the sql database engine)?
Not to offend, but I believe over 95% of the population runs js, and I believe that the potential to use video and photo multimedia in the web is just beginning to gain momentum. This is a good momentum by the way, as text is far too slow of a communication medium for our information age. Jquery is a marvelous way of combining our beautifully hand crafted sites with media and subconscious experiences…
Databases are used for virtually every PHP site out there, and a combination of cookies + DB is perfect (with the balance depending on your implementation). I think you could find some very interesting uses for this type of js, as well as so many other js scripts.
right…nobody likes “drag to share” or anything, you know, its totally useless, these draggable items…
Save the coords in a cookie would probably be enough. No database connection needed. Simple to implement. Nice to have the database functionality though.
jquery-ui-1.7.2.custom.min.js ????? That could be anything right?
“As a note,the jquery-ui file is a custom build which only includes the core and the draggable interaction functionality.”
What it is, is noted in the tutorial…
nice job !
No one mentioned it but I think you need to save it into database only when the page is unloading and there is a change in the initial positions. In a real world application, it will kill your server to post data after each drag-drop. On the other hand, using cookies will not have this problem.
Thank you very much! I now have ideas in my head for a fully dynamic CMS using Jquery, dynamic css, and the Zend Framework…
Nice! Would be useful as layout generator, if you listed the entries and selected a db specific entry, then position the elements to where that specific person left them. Really cool if it could output as xml format.