UnDefined

Jonahlyn's Personal Blog

jQuery UI Drag and Drop in a Backbone JS Application

| Comments

Recently I’ve fallen in love with Backbone.js. If you haven’t had a chance to check it out yet, I highly recommend it. It’s a framework for structuring javascript applications into models, views and collections. Yes collections. Just check it out.

Apparently, the way to learn any new javascript MVC framework is to study the todo list application built with it. (Check out this github repository to find the todo list app for your prefered framework.) The backbone todo list application is well documented in this split screen annotated source file that really helped me a lot. There is also a working example that I referenced quite a bit.

One thing that was obviously missing to me was the ability to drag and drop the todo items into a specific order. I did eventually find another version of the app that did have drag and drop but it looked to be implemented with mootools. Now I haven’t quite gotten around to learning mootools yet. Bad I know. I’m highly dependent on jQuery at this time so I wanted to figure out how to do it with jQuery and more specifically jQuery UI.

Googling didn’t lead me to any ready-made solutions so I decided to try to figure it out on my own. So here’s the solution I came up with.

First things first, jQuery and jQuery UI need to be included for this to work:

1
2
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>

Then I added a custom html5 data attribute to the todo div element in the javascript template and set the value to the model id. I did this so I would be able to associate the div back to its model later.

Add an data-id attribute to the todo div element
1
<%= id ? 'data-id="'+id+'"' : '' %>

Here’s what the entire template would look like:

1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/template" id="item-template">
  <div class="todo <%= done ? 'done' : '' %> " <%= id ? 'data-id="'+id+'"' : '' %>>
    <div class="display">
      <input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
      <div class="todo-text"></div>
      <span class="todo-destroy"></span>
    </div>
    <div class="edit">
      <input class="todo-input" type="text" value="" />
    </div>
  </div>
</script>

The todo list itself is simply a unordered list element with an id of “todo-list”. Inside the top level view ‘Appview’ inside the initialize function, I called the jquery UI sortable function on that unordered list. The update function passed to sortable will run after the drag and drop ordering has occurred. In this function, I loop through all of the divs in the list, get a reference to the todo model using the value of the data-id attribute and update the order property. Backbone seemed to take care of the rest.

1
2
3
4
5
6
7
8
9
this.$("#todo-list").sortable({
    update: function(event, ui) {
        $('div.todo',this).each(function(i){
            var id = $(this).attr('data-id'),
                todo = Todos.get(id);
            todo.save({order: i + 1});
        });
    }
});

Check out this jsfiddle if you want to play around with it.

This seems to work just fine but at this point I haven’t used it in any production applications so use at your own risk. That and I am still a backbone newbie so if you have any better ideas, please let me know.

Comments