Topic: Ajax Drag & Drop not updating (Up & Running Tutorial)

Hi Everybody,
I posted this question on Ruby Forum, but nobody responded, so I thought I would try here.  I don't think it's a tough problem to solve if you're experienced with Rails (I'm not!).

I've been working through the O'Reilly Ruby on Rails: Up and Running
book, and I'm having some problems with the Drag and Drop feature.  I've
gone over it several times, and I'm quite sure that my code is identical
to that displayed in the book, but the application is not running as
expected. I've been stumped on this for a few days now, so I thought I
would see if anybody has encountered this issue when working through the
tutorial and if anybody else might be able to help.

If you're not familiar with the book's tutorial, let me describe what
this application is supposed to do or the expected behavior [note: It
uses prototype.js, and effects.js and dragdrop.js from Script.aculo.us;
Also, I'm running Rails 1.1.2]:

There's a Slideshow Photos column and an Unused Photos column (by column
I mean divs or tables--areas on the page).  You're supposed to be able
to drag photos(thumbnails) back and forth between these two columns
(divs) and each time you do that, it's supposed to call either add_photo
or remove_slide and update the columns appropriately.  Also, you should
be able to drag slides(thumbnails) in the Slideshow Photos column up and
down to alter the order of slides in the slideshow.


Here's the behavior I'm observing:

1) Before dragging and dropping anything, everything looks fine; I can
drag slides within the Slideshow Photos up and down to change the order;
I can drag either the slide thumbnails or the photo thumbnails (in the
Unused Photos column) all over the page, but they won't stay there if I
try to drop them outside of the div that is allowed to accept them--they
just spring back to their starting spot. This is exactly as expected and
there's no problem here.

2) Dragging photos(thumbnails) from the Unused Photos column to the
Slideshow Photos column creates no problems whatsoever.  I can do this
repeatedly and it works as expected: the thumbnail gets added to the
Slideshow Photos column as a slide and at the same time it disappears
from the Unused Photos column.

3) The problem starts once I drag a slide (thumbnail) from the Slideshow
Photos column to the Unused Photos column.  The first time it works
correctly. I can drag a slide over, hold it over the Unused Photos
column, and it will fade slightly as it's supposed to and once I drop
it, both columns update appropriately (the thumbnail disappears from the
Slideshow Photos column and appears in the Unused Photos column).  But
after that first time, everything sort of goes berserk.

First of all, pictures in neither column spring back to where they're
supposed to be.  I can now drag a thumbnail or a slide all over the page
and drop it anywhere--it doesn't spring back.

When I drag a slide over to the Unused Photos column (or drag a photo to
the Slideshow Photos column)--the div that receives it, it no longer
fades.

If I drag and drop another slide from the Slideshow Photos column to the
Unused Photos column, the Unused Photos column will update but the slide
that was dragged over doesn't disappear. It just gets sent backward so
it's behind the other thumbnails after they've updated. And the
Slideshow Photos column doesn't update, so it has gaps wherever I've
dragged a slide away.

If I drag and drop a photo into the Slideshow Photos column, the
Slideshow Photos column will update, but the photo that was dragged over
doesn't disappear or move. I can pick it up again and drag and drop it
anywhere on the page.  I can drop it on the Slideshow Photos column
again and again (and get a lot of duplicate slides). Also, the Unused
Photos column doesn't update when I drag a photo from it and drop it
onto the Slideshow Photos column.

I think that describes it!  So to summarize, it works fine just the
first time and then everything gets screwy. Why is that?

I'd appreciate any suggestions. Thanks so much!

Rick



CODE:

# remove_slide is the method in the controller that is called when a
slide is
# dragged from the Slideshow Photos column and dropped into the Unused
Photos
# column

  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

# drop_receiving_element is the AJAX helper that calls the remove_slide
method.
# "slideshow-photo-picker" and "slideshow-photos" describe the divs that
# contain the Unused Photos column

<%= 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')
    ) %>

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

Can you post more code? Specifically the code used when dragging a slide from the Unused Photos column to the Slideshow Photos column. I'd like to compare it with the posted code to see if there is a significant difference which is breaking it. They should behave the same, correct?

Also, look near the beginning/end of the book and see if a URL is mentioned where the code can be found online - many times the author will provide the complete projects. Try downloading that and seeing if it has the same problem you are experiencing.

Railscasts - Free Ruby on Rails Screencasts

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

Hi Ryan,
Thanks for the help.  I did what you suggested (download the code), and the problem has gone away but I'm not sure why.  I switched in the code from the book, and everything worked as it was supposed to.  I then switched my code back in, intending to switch it out folder by folder to pinpoint where the problem was, but it turned out that it just started working.  In other words, I'm running the same code as before, but now it's working and before it wasn't.  It looks like switching the code out temporarily had some kind of an effect.  It's not like I hadn't restarted the server several times before that.  So really I have no idea what happened. Do you?

Thanks!
Rick

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

Were sessions involved in the code at all? Or maybe the data in the database changed? Otherwise I don't know what could have happened.

Railscasts - Free Ruby on Rails Screencasts

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

ryanb wrote:

Were sessions involved in the code at all? Or maybe the data in the database changed? Otherwise I don't know what could have happened.

Hi Ryan,
Yes, the code includes sessions.  Here's the remove_slide method for example, which is called when the thumbnail of the slide is dragged out of the slides div into the unused photos div.

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

My hunch was that it had something to do with sessions, but I'm not sure how exactly. Can you explain it now?

Thanks!
Rick

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

Putting model objects directly into a session like this can cause very tricky problems and inconsistencies - it is likely that this was your problem. When you tried the new code the session may have reset which ended up fixing the problem.

Instead of storing the model object itself in the session it is better to store the id of the model only then do a "Slideshow.find(session[:slideshow_id])" when you need to fetch the slideshow.

Railscasts - Free Ruby on Rails Screencasts

Re: Ajax Drag & Drop not updating (Up & Running Tutorial)

ryanb wrote:

Putting model objects directly into a session like this can cause very tricky problems and inconsistencies - it is likely that this was your problem. When you tried the new code the session may have reset which ended up fixing the problem.

Instead of storing the model object itself in the session it is better to store the id of the model only then do a "Slideshow.find(session[:slideshow_id])" when you need to fetch the slideshow.

That's awesome information to know. Thanks, Ryan!