Thomas Fuchs
Hi, I'm Thomas Fuchs. I'm the author of the script.aculo.us user interface JavaScript library, a member of the Prototype core team and a Ruby on Rails core alumnus.
You're using my JavaScript work every day, even if you're not aware of it!
@thomasfuchs on Twitter    Need consulting, corporate training or want me to speak at your conference? Contact me!

AJAX-enabled shopping cart, the movie

July 2nd, 2005

With the new drag-and-drop helpers coming with Ruby on Rails 0.13, you’ll be able to silly easily do stuff like this:

You know the drill, watch the video!

The above demo amounts to about 25 lines of code, including database acccess, session-based cart storage, add/remove items handling and the view rendering code (static HTML and CSS not counted).

It relies on the brand new draggable_element and drop_receiving_element helpers, that internally use the script.aculo.us libraries.

The code for making the product images draggable look like this:


<% for product in @products %>
  <%= image_tag "/images/products/product#{product.id}",
        :id => "product_#{product.id}",
        :alt => product.title,
        :class => "products"  %>
  <%= draggable_element "product_#{product.id}", :revert => true %>
<% end %>

And the cart drop handling code amounts to two helper calls:


<%= drop_receiving_element "cart",
      :update => "items", :url => { :action => "add" },
      :accept => "products", :hoverclass => "cart-active",
      :loading => "Element.show('indicator')",
      :complete => "Element.hide('indicator')" %>
<%= drop_receiving_element "wastebin",
      :update => "items", :url => { :action => "remove" },
      :accept => "cart-items", :hoverclass => "wastebin-active",
      :before => "Element.hide(element)",
      :loading => "Element.show('indicator')",
      :complete => "Element.hide('indicator')" %>

A partial serves to list the items in the cart:


<% session[:cart].each do |product,quantity| %>
<div>
  <% quantity.times do |i| %>
    <%= image_tag "/images/products/product#{product}",
          :class => "cart-items",
          :id => "item_#{product}_#{i}" %>
    <%= draggable_element "item_#{product}_#{i}",
          :revert => true %>
  <% end %>
  <span class="title">
  <%= Product.find(product).title + " (#{quantity})" %>
  </span>
</div><% end %>

Hope you put this stuff to good use!