Master Drag and Drop Technique using jQuery

Methods for developing drag and drop styles have been around for years. With the increase of programmers working for open source scripts like jQuery it's not a surprise we are seeing an upheaval of these older methods. The JavaScript library is very adaptive and offers some major improvements to our new age web.

We'll be going over a lucrative script you can use to create dynamic drag and drop boxes on your own website. The entire process is powered by jQuery functionality with a small script written out of the General Public License v3. This will save loads of time when it comes to development since many of the functionality has already been written! This also means this drag-and-drop library of code can be re-used on future projects and web apps.

Master Drag and Drop Technique using jQuery


Getting Content Ready

The first step is to develop a small project site. Inside a new folder we'll need just a few pieces. These are notably 2 new folders labeled "js" and "css" along with a blank index.html file. Our code will be very simple to understand and should provide a great jumping off point for future works.

Below is our bare-bones HTML file. Inside of our head we have 3 script inclusions with our main jQuery script being delivered from the Google Code servers. This shaves off an HTTP request every time the page is loaded which makes things much easier and quicker for every visitor. We've also included our style.css which contains some basic properties to lay out our document.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>DragnDrop Demo</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="js/jquery.dragndrop.js"></script>
    <script type="text/javascript" src="js/fn.js"></script>
    <link type="text/css" rel="stylesheet" href="css/style.css" />
</head>

<body>
<div class="dv1">
    <h2 class="handler">Drag me</h2>
    <div class="content">Yes, it is.</div>
</div>

<div class="dv2"><div class="gb">
    <h2 class="handler2">Drag me too</h2>
    <div class="content2">{ zIndex: 200, opacity: .9 }<br /><br /><small><strong>P.S. you can drag me from anywhere!</strong></small></div>
</div></div>

</body>
</html>

Inside of our body we have only two main divisions which will hold both of our drop boxes. The code is relatively straightforward and should be obvious what each piece is used to do. Inside each box we have headings set with a class of handler and handler2. These become important when dragging functions are called since each box behaves slightly different.

Google Code Homepage

Clear up CSS Styles

The HTML was fairly simple and shouldn't have slowed you down much at all. If you understand basic markup language then our CSS styles will also be a walk in the park. There isn't anything overly convoluted here. Most styles are used to define individual padding/margins and colors.

body,html { font-family:Calibri, sans-serif; background:#eaf3fb; font-size:12px; height:1000px; line-height:18px; }
p { height:30px; }

The body,html selector is only used for our demo page. This helps to keep things looking nice since the only content in our index file is the 2 drag boxes. This is also why our CSS properties have been slimmed down so much and can still accommodate the design feel.

.dv1 { width:200px; background-color:#eff7ff; border:1px solid #96c2f1; position:absolute; left:100px; top:100px; }
.dv1 h2 { background-color:#b2d3f5; padding:5px; font-family:Georgia, "Times New Roman", Times, serif; font-size:1.0em; text-transform:uppercase; font-weight:bold; color:#3a424a; margin:1px; cursor:move; }
.dv1 div { padding:5px; margin-bottom:10px; }
.dv2 { background-color:#f6ebfb; border:1px solid #a36fde; width:550px; position:absolute; cursor:move; left:400px; top:230px; }
.dv2 h2 { background-color:#eacfe9; letter-spacing:-0.09em; font-size:1.8em; font-weight: bold; padding:15px; margin:1px; color:#241f24; cursor:move; }
.dv2 .content2 { padding:5px; margin-bottom:10px; }

With both classes of .dv1 and .dv2 we have absolute positioning in place. This is not necessary at all and probably not the best way to lay out your drag boxes. However for this example it makes sense to lay out each box in a set location on every page reload. You may also notice font size and padding have been changed between the two classes. This has been applied to make distinguishing between the two easier with fewer risks.

Other than this, headings and inner division blocks are mostly similar. If you want to copy these styles point-for-point make sure to change each name before launching. For example it may be wiser to use IDs instead of classes in situations which call for a unique draggable box.

Breaking into JavaScript

Our two JavaScript files will contain all of the code needed to get these boxes working. I won't be covering areas of raw jQuery in detail since it's slightly out of scope of this article. This first file to give attention towards is jquery.dragndrop.js.

Inside we have the start of multiple functions, most notably Drags on line 22.

$.fn.Drags = function(opts) {
    var ps = $.extend({
        zIndex: 20,
        opacity: .7,
        handler: null,
        onMove: function() { },
        onDrop: function() { }
    }, opts);

This sets a return variable for Drags and also sets the initial data type towards a function. This is common practice seen between jQuery developers since you can save room in your code while also passing options between other functions. Inside we set a variable to extend each of the possible options passed between drag boxes.

jQuery Extend Documentation

The next two pieces of code include two event handler functions set to a variable of dragndrop. Both drag and drop are called as functions with an event parameter passed in. This event is going to occur when you click down on a box to drag and also when letting go.

var dragndrop = {
    drag: function(e) {
        var dragData = e.data.dragData;
        dragData.target.css({
            left: dragData.left + e.pageX - dragData.offLeft,
            top: dragData.top + e.pageY - dragData.offTop
        });
        dragData.handler.css({ cursor: 'move' });
        dragData.target.css ({ cursor: 'move' });
        dragData.onMove(e);
    },
    drop: function(e) {
        var dragData = e.data.dragData;
        dragData.target.css(dragData.oldCss); //.css({ 'opacity': '' });
        dragData.handler.css('cursor', dragData.oldCss.cursor);
        dragData.onDrop(e);
        $().unbind('mousemove', dragndrop.drag)
            .unbind('mouseup', dragndrop.drop);
    }
}

We can then see our function will manipulate the CSS positioning of each object. This will not affect your boxes if changed out of absolute positioning since each JavaScript function will overwrite any styles you've already defined. Further down we have code to check for function handlers and change other styles for cosmetic purposes. These can include opacity reduction, font styles or colors, or the addition of new paragraphs.

Raw Drag/Drop Functions

Into our second file fn.js we can see the code isn't too complicated. We are checking through jQuery when the object or document is finished loading to call our core functions. Inside we define two instances of the Drags function we examined earlier.

You can tell the two blocks contain .dv1 and .dv2 classes. If you wish to have only 1 draggable box then removing the second piece of code will save you some room. On the other hand adding new boxes isn't a problem but will require new functions to be set up inside this file.

The first things we set are options based through variable names we examined earlier. The biggest requirement for each definition is setting a handler name. This will be used to tell jQuery event handlers when you're clicking or releasing a certain piece of your document. These can be class or ID definitions and can also be DOM oriented, if you find that easier.

Inside of our first function you'll notice two event handlers onMove and onDrop. Both of these call a new function passing in the current event as variable e. From here we are manipulating the HTML inside of the box to update with each movement. This is a neat effect to demonstrate just how much control you can have using simple jQuery events.

jQuery Written Model

In our second function call we only have a few more properties set, namely z-Index and opacity. You are able to add more if you please but this will require you to edit the former JavaScript file to check property settings. As an example you could pass in new font styles or width/height variables based on which box is being moved – a very nifty trick indeed!

Conclusion

With just a little bit of work and some open source code we are able to develop one amazing drag and drop interface. jQuery offers enormous benefits to developers who are impatient about re-inventing the wheel. Along with this backend interface comes new ways of defining data.

We not only have event-based functions but may also pass new variables into each drag box. This gives way to countless new opportunities for creativity. Our demo gives just a brief idea of what is possible through this code. If you'd like to delve deeper check out the jQuery Documentation for details on library functions and proper syntax.

Opinions expressed in this article are those of the author and not necessarily those of Onextrapixel.