Home arrow Ruby-on-Rails arrow Page 4 - Finishing a Shopping Cart Implementation

Finishing a Shopping Cart Implementation

In this second part of a two-part series on implementing a shopping cart for an online bookstore, we'll create a floating cart that will show its contents to the user, and set up its capabilities. This article is excerpted from chapter five of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 11
June 04, 2010
  1. · Finishing a Shopping Cart Implementation
  2. · Implementing the Add Items to the Cart User Story
  3. · Ajax’ing It
  4. · Drag-and-Drop
  5. · Implementing the Remove Items from the Cart User Story
  6. · Implementing the Clear the Cart User Story

print this article

Finishing a Shopping Cart Implementation - Drag-and-Drop
(Page 4 of 6 )

Although the Add Items to the Cart user story is now fully functional, there is one thing George still wants us to implement: drag-and-drop shopping. Fortunately, with the functionality that is already in place, adding that capability is very easy.

First, we need to make the books in the catalog pages draggable. Make the highlighted changes toapp/views/catalog/_books.rhtml:

<ul id="books">
  <% for book in @books %>
  <li class="book" id="book_<%= book.id %>">

      <dt><%= link_to book.title.t, :action => "show", :id => book %></dt>
    <% for author in book.authors %>
      <dd><%= author.last_name %>, <%= author.first_name %></dd>
    <% end %>
      <dd><%= pluralize(book.page_count, "page") %></dd>
      <dd>Price: $<%= sprintf("%.2f", book.price) %></dd>
      <dd><small><%= 'Publisher'.t %>: <%= book.publisher.name %></small></dd>
          <%= add_book_link("+", book) %>
  <%= draggable_element("book_#{book.id}", :revert => true) %>
  <% end %>

We changed the list to an unordered list and gave each book a list element of its own, so that it can be referenced uniquely by itsid(for example,book_75). Then we made each book item a draggable element with thedraggable_elementmethod. Stating:revert => truein the call makes the item slide back to its original position when the mouse button is released during dragging. If you now reload the catalog page in a browser, you can drag the catalog items around the browser window.

To make each item look more like an individual element, we need to style the list a bit. Add the following at the bottom ofpublic/javascripts/style.css:

#books {
  list-style: none;
  padding: 0;
  float: left;

#books .book {
  float: left;
  border: 4px solid #ccc;
  background-color: #fff;
  margin: 10px;
  padding: 5px;
  cursor: pointer;

The second part of implementing drag-and-drop functionality in a Rails application is to define an element as a drop-receiving element. This is done using the (surprise!)drop_receiving_elementhelper. Inapp/views/layouts/application.rhtml, add the following code after theshopping_cartelement:

  <div id="shopping_cart">
  <%= render :partial => "cart/cart" %> 
<%= drop_receiving_element("shopping_cart", :url =>
      { :controller => "cart", :action => "add" }) %>

This makes theshopping_cartdivision act as a receiver for the dragged book items. Whenever a book is released over the shopping cartdiv, an Ajax call to theaddaction ofCartControlleris made. You can test this by reloading the catalog page and dragging a book to the cart. The log file should show something like the following:

Processing CartController#add (for at 2006-10-09 15:07:07) [POST]
  Session ID: bc2009ee48c083165c6196ac7ff4b44c
  Parameters: {"action"=>"add", "id"=>"book_22", "controller"=>"cart"}

[4;35;1mCart Load (0.000296) [0m [0mSELECT * FROM carts WHERE (carts.id = 1654)
LIMIT 1 [0m 
[4;36;1mBook Load (0.000420) [0m [0;1mSELECT * FROM books WHERE (books.id =
'book_22') LIMIT 1 [0m  





ActiveRecord::RecordNotFound (Couldn't find Book with ID=book_22):

You can see that theidpassed to theadd action is the DOMidof the dragged element. However, since theadd action wants only the actualidof the book (22in this case), we need to clean up the passed value a bit. Add the highlighted code to

  def add
params[:id].gsub!(/book_/, "")
@book = Book.find(params[:id])

gsub!is a method that can be used to replace parts of aStringobject in place. It takes two parameters: a regular expression that is to be sought in the string and a replacement string. In our case, we want to remove thebook_in front of the actualidnumber, so we replace it with an empty string. After the call,params[:id]has only the numericidof the book in question and can thus be used in theBook.findcall on the following line. If the expression is not found in the string—which is the case when the action is called normally by clicking the + link, resulting inparams[:id]being22, for example—the string is left untouched.

That was everything needed to make drag-and-drop work. We’re now ready with the first functionality of our shopping cart: adding items to it. Run the functional tests, see them roar through, and finally try out the cart in your browser (see Figure 5-2), basking in the glory of being an Ajax developer. If you want to make sure the system works even without Ajax, turn off JavaScript in your browser and try to add items to your cart the old-fashioned way.

Figure 5-2.  Adding an item to the cart

blog comments powered by Disqus

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials