A collection of computer systems and programming tips that you may find useful.
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Wednesday, November 26, 2008

Rails - Drag and Drop Sorting in a Table

Through use of the Prototype and Script.aculo.us libraries, Rails makes it easy to set up drag and drop capability in your pages.

But all the examples I've seen use Lists of elements and I typically use Tables to display sets of data. I was having a hard time getting drag and drop sorting to work but I got there.

My problem was that I was putting my 'container id' into the <table> tag. That doesn't work. You have to have a <tbody> tag pair inside there - which I simply have never bothered with. Put the 'container id' in there and put the 'element id' in the <tr> tag - not the <td> tag.

In this dummy application you have carts and carts have multiple items. The order of each item in the cart is given by the item 'position' field.
class Cart < ActiveRecord::Base
has_many :items, :order => :position

class Item < ActiveRecord::Base
belongs_to :cart
acts_as_list :column => :position, :scope => :cart

This would go into your cart show page:
<tbody id="cart_div">
<% @cart.items.each do |item| %>
<tr id="item_<%= item.id %>">
<td><%= item.position %></td>
<td><%= item.name %></td>
<% end %>

Then elsewhere in that page you need to add this block that sets up the JavaScript magic. Note that you need to specify the tag that will get dragged and dropped. The default is 'li' but here we want 'tr'.
<%= sortable_element 'cart_div',
:url => { :action => 'sort', :id => @cart },
:complete => visual_effect(:highlight, 'cart_div'),
:tag => 'tr'

You also need to create a 'sort' action in your carts controller that looks something like this:
  def sort
@cart = Cart.find(params[:id])
@cart.samples.each do |cart|
item.position = params['cart_div'].index(item.id.to_s) + 1
render :nothing => true

Note that you don't need to do anything with your routes.rb file, even though 'sort' is not a standard action. I assume that is because it is using a GET and that just gets handled?

Finally, you need to include the javascript libraries in your page layout, but you knew that already.
<%= javascript_include_tag :defaults %>


dMan01 said...

Thanks a million. I was going nuts trying to figure this one out.

K said...

Throwing in tbody seems so simple - but it works. Thanks for the example!

springwind said...

Thanks a lot. just wondering how to highlight the row ...

Ease said...

Thank you! Thank you!

brinkka said...

I recently came across your blog and have been reading along. I think I will leave my first comment. I don’t know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
By : http://www.factspenisenlargement.com

hibeyond said...

black boots

Chocolate boots

sand boots

Chestnut boots

gray boots

pink boots

grey boots
pink boots

Black Ugg Boots

Chestnut Ugg


Chocolate Ugg


Grey Ugg Boots

Ugg Boots On Sale

Archive of Tips