Programming - - By Alexis Goldstein

A Drag and Drop Planning Board with HTML5

The Drag and Drop API is one of the new JavaScript APIs that let us add dynamic effects to our sites. There are two flavors of Drag & Drop:

1. Dragging elements into other elements, as defined in the Drag and Drop W3C spec.

2. Dragging files from your computer and into a webpage, in combination with the File API.

In this article, we’ll be focusing on the former. To learn more about the latter, an excellent guide can be found at the Mozilla Developer Network.

We’ll be building a simple agile planning board. We’ll have three categories: To Do, In Progress, and Done. We can move the items around on the board to mark their progress.

note: Planning Boards

The concept of a Planning Board or a Task Board is a part of the Scrum Agile software development methodology. To learn more, see: http://en.wikipedia.org/wiki/Scrum_(development)

To give you an idea of what we’re going to build, here’s a picture of the finished product. You can see the finished code on github:

Drag and Drop Planning Board

Let’s dive in, starting with the HTML!

<div id="board">
  <div id="todo">
    <div id="item1">
    <div id="item2">
  </div>
  <div id="inprogress"></div>
  <div id="done"></div>
</div>

Our first div, div id=”board” will act as the main container. The board will be divided up into three other divs. Finally, several smaller divs will act as note cards holding our items. The note cards will start in the “To Do” section.

Here are the complete set of steps we’ll need to make our notecards draggable into the other sections of the bulletin board:

  1. Set the draggable attribute on our notecard div HTML elements.
  2. Add an Event Listener for the dragstart event on the notecards.
  3. Add an EventListener for the dragover event on all sections of our bulletin board.
  4. Add an EventListener for the drop event on all sections of our bulletin board.

First, we’ll add the draggable attribute to our two notecards.

<div id="board">
  <div id="todo">
    <div id="item1" draggable="true">
    <div id="item2" draggable="true">
  </div>
  <div id="inprogress"></div>
  <div id="done"></div>
</div>

Next, we need to specify the JavaScript code that will actually make the Drag and Drop magic happen.

First, we’ll bind the dragstart event to our two notecards. We’ll do this via jQuery’s bind method, binding the dragstart event on either of our two notecards to the code inside an anonymous function :

$('#item1, #item2').bind('dragstart', function(event) {
  event.originalEvent.dataTransfer.setData("text/plain", event.target.getAttribute('id'));
});

In our anonymous function, we call the setData method, which is a method on the DataTransfer object. The DataTransfer object is one of the new objects outlined in the Drag and Drop API. This object allows us to store and retrieve data about the objects that are being dragged.

The setData method takes two arguments:

  1. The drag data item kind. This describes what kind of data we’ll be storing
  2. The actual data we want to store. This is either a unicode or binary string.

The setData method adds the data we want to store about the dragged item to what the W3C spec calls the “drag data store“.

Examining the line inside our anonymous function more closely, we can see that we’re calling setData on the dataTransfer object, and specifying both required arguments:

event.originalEvent.dataTransfer.setData("text/plain", event.target.getAttribute('id'));

We set our drag data item kind to be “text/plain”. And for the data itself, we’ll store the id of the notecard that we have begun to drag.

By default, the dragged item is shown to be a ghost-like image of the original element. If you’d like to change the dragged image to a custom one, you can use dataTransfer’s setDragImage() method.

Next, we need to make sure we can drag the notecards over onto the other sections of the bulletin board. To do so, we’ll bind the dragover event on the board sections. Again, we’ll do this via jQuery’s bind method:

$('#todo, #inprogress, #done').bind('dragover', function(event) {
  event.preventDefault();
});

This time, the code inside our anonymous function is considerably more simple. But what is it doing?

By default, none of the all elements on the page will accept a dropped item. In order to override this default behavior, and enable the element to accept dragged items, we must pervent the default behavior from happening. We do this by calling the preventDefault() method on the event.

For our last step, we need to actually do something once our notecards are dropped onto a new section of the bulletin board! As a first step, we’ll bind the drop event to the bulletin board sections, and define what to do once something is dropped onto them. Again, we do this by binding the bulletin board divs to an anonymous function, via jQuery’s bind method:

$('#todo, #inprogress, #done').bind('drop', function(event) {
    // do something!
});

We want to drop the whole div element for the dragged notecard into the new location. To do this, we first grab the notecard element’s id, which we previously stored to the dataTransfer object:

$('#todo, #inprogress, #done').bind('drop', function(event) {

  var notecard = event.originalEvent.dataTransfer.getData("text/plain");

});

Next, we’ll actually add a new element to the target, by using the appendChild method:

$('#todo, #inprogress, #done').bind('drop', function(event) {

  var notecard = event.originalEvent.dataTransfer.getData("text/plain");

  event.target.appendChild(document.getElementById(notecard));
});

Finally, as we did before, we’ll disable the default behavior that disallows any items to be dropped:

$('#todo, #inprogress, #done').bind('drop', function(event) {

  var notecard = event.originalEvent.dataTransfer.getData("text/plain");

  event.target.appendChild(document.getElementById(notecard));

  event.preventDefault();

});

Now, we can move our notecards around into any section we want!

Drag and Drop Planning Board

See the demonstration page. View source for the full code.

To learn more about HTML5’s Drag and Drop, check out my forthcoming book, HTML5 and CSS3 for the Real World. You may also find the following sites useful:

Sponsors