Ruby on Rails with Ajax: Modifying the Slide Show - Adding a Dropped Photo
(Page 3 of 4 )
Now we need to create the add_photo method to actually add a dropped photo to the slideshow. Edit photos/app/controllers/slideshows_controller.rb, and add this:
def add_photo
slideshow_id = session[:slideshow].id
photo_id = params[:id].split("_")[1]
slide = Slide.new()
slide.photo_id = photo_id
slide.slideshow_id = slideshow_id
if !slide.save
flash[:notice] = 'Error: unable to add photo.'
end
@slideshow = Slideshow.find(slideshow_id)
session[:slideshow] = @slideshow
render_partial 'show_slides_draggable'
end
Let's walk through this code:
slideshow_id = session[:slideshow].id
This line retrieves the current slideshow from the session hash and gets the slideshow's id.
photo_id = params[:id].split("_")[1]
The id attribute of the dropped photo get passed as the :id parameter. If you recall from the photo_picker template, we set those ids to values such as "photo_1" and "photo_19", so the remainder of this line of code splits the string on the underscore, grabs the second half, and assigns it to photo_id.
The next five lines create a new slide, assign to it the photo id and the slideshow id, and then save it to the database.
Finally, we render and return the show_slides_draggable partial, after setting @slideshow to the current slideshow (which is needed by the partial template).
All that code handles dragging new photos to add to the slideshow. Now we just need to add a little more code to implement dragging a photo from the slideshow to the unused photos list as an intuitive way to remove photos from the slideshow.
The displayed list of photos in the slideshow are already draggable because we made them into a sortable list. The only problem with the current implementation is that the photos can be dragged vertically only. They need to be dragged both vertically for reordering and horizontally to the unused photos column.
We can drag the photos only vertically because the default option for a sortable list is :constraint => 'vertical'. Fortunately, you can change this by editing the file photos/app/views/slideshows/_show_slides_draggable.rhtml and changing the call to the sortable_element helper to add this :constraint option:
<%= sortable_element('sortable_thumbs',
:url => {:action => 'update_slide_order'},
:constraint => '') %>
Now you can drag those photos anywhere. But you still need to make the unused photos list into a drop receiver that uses Ajax to remove the dropped photo from the slideshow.
To do so, edit photos/app/views/slideshows/edit.rhtml, and add this at the end:
<%= drop_receiving_element("slideshow-photo-picker",
:update => "slideshow-photos",
:url => {:action => "remove_slide" },
:accept => "slides",
:droponempty => "true",
:loading => visual_effect(:fade),
:complete => visual_effect(:highlight, 'slideshow-photos')
) %>
This code is almost identical to the other drop_receiving_element we used. The difference is that the target is the slideshow-photo-picker, and the action taken on a drop is to call the remove_slide method. Also, notice that you can drop only "slides" here (that is, HTML elements with a class attribute of slides). If you go back and take a look at how we defined the partial template photos/app/views/ slideshows/_show_slides_draggable.rhtml, you will see that we did, indeed, make each item in the sortable list a slide.
Add the remove_slide method to photos/app/controllers/slideshows_controller.rb:
def remove_slide
slideshow_id = session[:slideshow].id
slide_id = params[:id].split("_")[1]
Slide.delete(slide_id)
@slideshow = Slideshow.find(slideshow_id)
session[:slideshow] = @slideshow
@photos = unused_photos(@slideshow)
render_partial 'photo_picker'
end
In this code, you get the id of slide you want to remove, and then delete it from the slide database table. Remember, this action does not delete the photo from the database. The slide data says what photos are in a given slideshow, and deleting an entry from the slide table removes that slide from its slideshow. Finally, you render the HTML for the photo picker, which now includes the removed slide.
I'll bet you're anxious to see all this in action. All you need to do is to update the style sheet and then try it out. Edit photos/public/stylesheets/slideshows.css, and add the following:
#slideshow-photo-picker {
float: left;
width: 10em;
text-align: center;
border-right: thin solid #bbb;
padding: 0.50em;
padding-bottom: 10em;
}
img.thumbnail {
border: 2px solid black;
margin-bottom: 1em;
}
img.photos {
border: 2px solid black;
margin-bottom: 1em;
}
Whew! That's it: try it now!
The first thing you'll notice is that the Unused Photos section is empty (see Figure 6-5). That's because all the photos are currently in the slideshow. Just drag a few of the slides out of the slideshow and drop them into the Unused Photos column; then you'll have something more like Figure 6-6.
Next: Filtering by Category >>
More Ruby-on-Rails Articles
More By O'Reilly Media
|
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.
|
|