Ruby-on-Rails
  Home arrow Ruby-on-Rails arrow Page 2 - Ruby on Rails with Ajax: Modifying the Sli...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
RUBY-ON-RAILS

Ruby on Rails with Ajax: Modifying the Slide Show
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 3
    2007-08-02

    Table of Contents:
  • Ruby on Rails with Ajax: Modifying the Slide Show
  • Drag and Drop Everything (Almost Everything) continued
  • Adding a Dropped Photo
  • Filtering by Category

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    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.

    More Ruby-on-Rails Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Ruby on Rails: Up and Running," published...
     

    Buy this book now. 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). Check it out today at your favorite bookstore. Buy this book now.

    RUBY-ON-RAILS ARTICLES

    - Iterating and Incrementing Strings in Ruby
    - Comparing and Manipulating Strings in Ruby
    - Strings in Ruby
    - Ruby On Rails: Making Your First Dynamic Site
    - Ruby on Rails: Beginning Rails
    - Ruby: Modules, Mixins, Fixins, and Rails
    - Controlling Information Access with the Rail...
    - URLs, Filters and the Rails Action Controller
    - Flash and the Rails Action Controller
    - Rails Action Controller
    - Dropping and Sorting with AJAX and script.ac...
    - Drag and Drop with script.aculo.us and Rails
    - Introducing script.aculo.us
    - Ruby Classes and Objects
    - Ruby Loops






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway
    Stay green...Green IT