Home arrow Ruby-on-Rails arrow Page 2 - Ruby on Rails with Ajax: Modifying the Slide Show
RUBY-ON-RAILS

Ruby on Rails with Ajax: Modifying the Slide Show


In this conclusion to a two-part article, you'll learn how to drag and drop slides in our example slideshow to modify it, and how to filter by category. This article is excerpted from chapter six of the book Ruby on Rails: Up and Running, written by Bruce A. Tate and Curt Hibbs (O'Reilly, 2006; ISBN: 0596101325). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 3
August 02, 2007
TABLE OF CONTENTS:
  1. · Ruby on Rails with Ajax: Modifying the Slide Show
  2. · Drag and Drop Everything (Almost Everything) continued
  3. · Adding a Dropped Photo
  4. · Filtering by Category

print this article
SEARCH DEVARTICLES

TOOLS YOU CAN USE

advertisement
Ruby on Rails with Ajax: Modifying the Slide Show - Drag and Drop Everything (Almost Everything) continued
(Page 2 of 4 )

Finally, notice two Ajax related helpers: drop_receiving_element and observe_field. We'll come back to these in a little bit after we have discussed some prerequisite details.

Now, make these changes to photos/app/controllers/slideshows_controller.rb, replacing the edit method and creating the unused_photos method:

  def edit
    @slideshow = Slideshow.find(params[:id])
    session[:slideshow] = @slideshow
    @photos = unused_photos(@slideshow)
  end

  def unused_photos(slideshow)
    all_photos = Photo.find(:all)
    candidates = []
   
for photo in all_photos
      in_slideshow = false
      for slide in slideshow.slides
           if slide.photo.thumbnail === photo.thumbnail
              in_slideshow = true
              break
          
end
      end
      candidates << photo if not in_slideshow
   
end
    return candidates
  end

The purpose of this code is to retrieve all the data needed by the edit.rhtml view template:

@slideshow = Slideshow.find(params[:id])

The id of the slideshow that you want to edit is passed in the request parameters from the browser. Here you retrieve that id and read that slideshow from the database, which you store in the instance variable @slideshow to make it available to the view template.

session[:slideshow] = @slideshow

Ajax actions requests will be coming in as the user makes changes, and you need to know what slideshow to change. This line saves a reference to the slideshow in the session hash. I'm using a key value of :slideshow to save and retrieve this from the session, but that value is arbitrary and could have been any unique identifier.

@photos = unused_photos(@slideshow)

This line calls the new method unused_photos to retrieve a list of all photos that are not in the slideshow; it then saves that list in @photos.

def unused_photos(slideshow)

This method returns a list of photos that are not in the slideshow. The logic should be self-explanatory. First, create an empty array (candidates = []), and then iterate through the list of all photos, adding them to the array (candidates << photo) if they are not already in the slideshow. The technique used here is grossly inefficient, but it will suffice for our purposes.

We still need to create the photo_picker template that generates the HTML to display all the photos that can still be added to a slideshow, so go ahead and create the file photos/app/views/slideshows/_photo_picker.rhtml with this in it:

  <% for photo in @photos %>
     
<%= image_tag("photos/#{photo.thumbnail}",
                     :style => "vertical-align: middle",
                     :id => "photo_#{photo.id}",
                     :class => "photos") %>
      <%= draggable_element "photo_#{photo.id}", :revert => true %>
  <% end %>

This template iterates through the list of photos in @photos. For each photo, it uses the image_tag helper to create an HTML image tag and the draggable_element helper to generate the JavaScript code that makes it draggable. You can see that the first parameter of draggable_element matches the value of the id attribute (:id => "photo_#{photo.id}") on the image tag. The draggable_element helper expects the id of the HTML element that it should make draggable, followed by zero or more options. The single option used here (:revert => true) says to move the element back to its original position after it is dropped.

But where can these draggable images be dropped? Recall that at the end of the slideshow's edit.rthtml template we had:

  <%= drop_receiving_element("slideshow-contents",
           
:update => "slideshow-thumbs",
           
:url => {:action => "add_photo" },
           
:accept => "photos",
           
:droponempty => "true",
           
:loading => visual_effect(:fade),
           
:complete => visual_effect(:highlight, 'sortable_thumbs')
           
) %>

Just like the draggable_element helper, the drop_receiving_element helper expects the ID of the HTML element onto which you can drop something that was declared as draggable. The remaining parameters are options that given as name/value pairs (the order is not important). These options are doing a lot, so let's go through them one at a time:

:update => "slideshow-thumbs"

This gives the ID of the HTML element that should be updated when a photo is dropped on our slideshow-contents div. The :position and :url options say how, and with what, that HTML element should be updated. When the :position option is omitted (as it is here), the HTML returned from the server replaces the target elements HTML. The :position option says that the returned HTML should be inserted into target element, instead of replacing it. The value :position can be specified as :before, :top, :bottom, and :after.

:url => {:action => "add_photo" }

This option constructs the URL that is sent to the server (via a background Ajax request) when a photo is dropped (you've seen this before). This executes the add_photo method in the current controller (the SlideshowsController). The add_ photo action adds the dropped photo to the slideshow and returns an HTML fragment that will replace the existing HTML in the target element, which, as you will see, is a rerendering of the slideshow's contents, which now include the added photo.

:accept => "photos"

Without this option, you could drop any draggable element here. However, this line says that only HTML elements that have the class attribute "photos" can be dropped here. Remember that in our photo picker template we gave each photo class attribute of "photos".

:droponempty => "true"

This option says that the user can drop photos here even if the target is completely empty.

:loading => visual_effect(:fade)
:complete => visual_effect(:highlight, 'sortable_thumbs')

:loading and :complete (plus a few more events) specify client-side JavaScript event handlers that are executed at specific points in the progress of the Ajax request. In both cases, we are displaying a visual effect that gives the user positive feedback. The :loading event occurs when the browser begins loading the response, and the :complete event occurs when its all finished. The code specifies that the dropped photo will fade until it becomes invisible. It also highlights the target area on which the photo was dropped.


blog comments powered by Disqus
RUBY-ON-RAILS ARTICLES

- 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
- Ruby on Rails Templates and Layouts
- Action Pack Controller Creation
- Writing an Action Pack Controller

Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 



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