views:

25

answers:

1

Hi there, This seems like it should be straight-forward, but I'm stumped. I have a link to a view controller that ends up using send_data to download a file to the user's hard drive. This works very well, and it leaves the current view apparently untouched.

But now I would like the page to provide some feedback after that download is complete. I naively put something like the following code in the controller before the send_data method call:

flash[:notice] = "Nice work, hot shot!"
send_data file, :filename=>fullname+".txt", :type=>"text/plain"

But that doesn't work, because the current view doesn't reload to give me a chance to display the flash var.

I've also tried adding an RJS view for this action, but that resulted in the old DoubleRender error, because send_data is a render action as well.

So... uh... how the heck would one pass data back to the current view after running send_data? Or is there another approach to this problem?

Thanks! Aaron.

+1  A: 

Hi Aaron,

Perhaps you could set a cookie in the response and poll for that cookie with javascript when the link to download the file is clicked.

The cookie can be set like this:

cookies["download_finished"] = "true"
send_data file, :filename=>fullname+".txt", :type=>"text/plain"

Then just periodically for that cookie using your favorite javascript framework.

Jason stewart
Interesting idea! Having played around with this, I'm having trouble getting it to work. The cookie can be set in the controller action, but it won't be checked until the page reloads. So I can download the file and nothing happens. But when I manually refresh the page, boom! Interval checking kicks in and detects the cookie. Hmmm...
Aaron Vegh
Yes, I got it working! Just a quick rundown: in the controller action, I set the cookie, but you have to include the domain and path like so: cookies[:download_complete] = { :value => "true", :domain => "localhost", :path => "/" }
Aaron Vegh
[sorry, submitted prematurely] -- then in the view, I have this code at the top: <script> var theInterval = self.setInterval("checkCompleteCookie()", 1000);</script> which calls a javascript function that uses a jQuery cookie plugin which checks for that cookie; if found, it reloads the page and rubs out the cookie using the same info as the setting cookie: $.cookie('download_complete', null, { domain: "localhost", path: "/" }); This prevents the page from constantly reloading. Great answer, thanks very much!
Aaron Vegh