jQuery: Customizable layout using drag and drop

Amazed by features like drag and drop, customizable content and AJAX? Learn how you can combine them to create a customizable website layout, saving preference using cookies.
Wanna cut to the chase? Check out the final example or download them all.
View the final example Download all examples
Requirements
My approach includes using jQuery along with the jQuery UI Sortable plugin for drag and drop functionality and the jQuery Cookie plugin for storing item positions.
These files are used in examples related to this article.
- jQuery 1.4.2
- jQuery UI 1.8.0
- jQuery Cookie 1.0 (rename to jquery.cookie.js)
jQuery needs to be loaded before jQuery UI and jQuery Cookie.
Note: Don't forget that JavaScript and cookies has to be enabled!
1. Getting started with sortable lists
Before we can create a customizable layout we need to be able to change the order of items.
A single sortable list
Using the Sortable plugin of jQuery UI, we can create a "sortable list", which enables you to re-order items in the list using drag and drop.
Sortable and connectable lists
Using the parameter connectWith (jQuery selector) we can define which other lists that items within a list can be dragged and dropped to.
Now this isn't exactly what you would call a customizable layout, however it is one step in the right direction. Imagine that the list was filled with sidebar items instead of plain containers.
What's left is in some way to get, save and load the item positions, but before I cover how to do that, I'll do a short demonstration of some of the other options available for Sortables.
Sortable and connectable lists with visual helper
Using a visual helper to indicate where the item will be positioned when dropped is good for usability. This is enabled using the option placeholder (CSS class).
Sortable and connectable lists (within containment)
Sometimes it's unnecessary to be able to drag items freely around a website, using the containment (DOM element, 'parent', 'document', 'window', or a jQuery selector) option we can choose to contrain drag within the bounds of the specified element.
2. Saving and loading items
Beeing able to customize a layout is great, however it's useless if you had to customize it all over again when you re-visit the page. We need to remember the positions of the items, this is where the jQuery Cookie plugin comes in.
Get items
First of all, we need a method to retrieve the items within a Sortable list. Because we indend to save the items in a cookie, we need a string representation of the items.
This can be achieved by combining the JavaScript function join(), which joins all elements in an array separated with a specified separator, with the .sortable('serialize') method which serializes the sortable's item id's into an array.
That's nice, but we also need a way to store items when we have connected lists (columns). We can do this by looping through each list within a container and for each list its items and then join all the items together with a separator.
Now we have the item string ready!
Save items
Using jQuery Cookie to get, set and delete cookies - is a piece of cake ;).
Save items automaticly
We don't want to push a "Save positions" button whenever we have changed the order of items, instead we want it to happen automaticly.
The Sortable event update, is executed each time sorting has occurred, we just have to enter a little bit of code that saves the item order to a cookie whenever this event is triggered.
Now, whenever sorting has occurred, the item positions will be saved to a cookie named "items".
Note: we don't need to include the parameters event and ui since we aren't using them.
Load items
Loading items is somewhat the reverse of saving items, we need to extract columns and items from our item string and then render each item.
I have separated the loading process into two functions, loadItemsFromCookie() and renderItems().
Running this code would result in the same HTML we had before:
That's basically it, we now know how to sort, save and load items. This is all we need to know in order to create a customizable layout. Finally we can take our knowledge and put together and apply it to a real design.
3. Implementation in a real design
I've chosen to use a modified version of my website template Simple Organization for this example.

Making this design customizable is really straight forward, the only changes we have to make is to put all items that we want to cusomtize into Sortable lists and change our functions a little bit. For example we don't need to bother about columns (connected lists).
Loading content using AJAX
To make it more realistic, I have put the contents of the customizable items into separate HTML files and load them using AJAX in the rendering proccess. All we have to do is to change a bit of code in renderItems().
The div with class loader (loading spinner image) is replaced with the contents of the HTML file as soon as the AJAX-call is complete.
Additional options
For the final example, I have used some options that I haven't explained before:
Code from example
handle(jQuery selector) - defines where on an item dragging is possible.axis(x/y) - defines in which direction dragging is allowed.opacity(float) - opacity of the item beeing dragged.forceHelperSize(boolean) - forces the helper (droppable area) to have a size.forcePlaceholderSize(boolean) - forces the placeholder (visible helper) to have a size.
Learn more about these options among others in the jQuery Sortable documentation.
The End
I hope you enjoyed my article and that your have learned something. I'm new to writing articles so any feedback is very appreciated.
Good luck with creating customizable layouts!
Hey!
Thanks for the guide, it helped me alot :)
I’d like to ask how did you configure in the final example that a sortable will only be able to be grabbed on its top and not on the entire block?
I used the
handleoption, I’ll update the article describing the additional options used asap.Thanks a lot, it works :)
Another question – do you have any idea how to make the cookie not expire after the browser closes? I want it to stay indefidently.
Yes, you can specify expiration using a third parameter (accepts an object with properties). Example
$.cookie(name, value, { expires: 999 }), this will set the cookie expire in 999 days.In Example 2.3, how do I change the code so the Cookie is loaded automatically? Without the use of a button.
You can bind a function to be executed whenever the page has loaded successfully using
$(document).ready().So to automaticly load items from a cookie on page load, just call
loadItemsFromCookie()from the function placed within the$(document).ready()event.Example:
$(document).ready(function(){
loadItemsFromCookie('cookie-name');
})
Hi,
Great and clean tutorial :-)
Thanks.
This is indeed a great tutorial. Thanks a lot for this. I will surely create a POC. Will let you know if have any question.
This is awesome!! Thanks a lot.
I will use this for a project ;)
Hi. Your final example seems to work in IE7, but other examples don’t work. I tried to troubleshoot but didn’t have any clue whatsoever. Do you mind to look into it?
This is a great work though. Thanks.
Ok, I have found the out what’s the problem with IE.
connectWith must be put at the very last:
$(‘#content .sortable-list’).sortable({
opacity: 0.7,
placeholder: ‘placeholder’,
connectWith: ‘#content .sortable-list’
});
This works now. Thanks.
Strange, these items not saved for me. Latest FF, cookies enabled
I found another sample which working fine. http://www.daviferreira.com/blog/exemplos/draganddrop/exemplo2.html
Oh, that cool. Thanks the guide for me
thanks a lot for this, has helped me as well !!
Very cool and clear. Thank you.
It is very helpful article.
Thanks for sharing your code, very nice article.