views:

694

answers:

2

I want to upload and then process a file in a Ruby on Rails app. The file upload is usually quite short, but the server-side processing can take some time (more than 20 seconds) so I want to give the user some indicator - something better than a meaningless 'processing...' screen.

I'm trying to use the following code in the view

<%= periodically_call_remote(:url => {:action => 'progress_monitor', :controller => 'files'},
                 :frequency => '5',
                 :update => "setProgress('progressBar','5')"
                 ) %>

The content of the :update parameter is the javascript I want to run every 5 seconds

and the following code is in the files controller

def progress_monitor
  render :text => 'whatever'
end

Eventually the progress_monitor method will return the current progress as an integer (% complete) and that will be passed into the 'setProgress' javascript code (that will update an on screen element)

However, I'm struggling to get a correct response from from the server that can then be passed into javascript.

Can anyone help, or am I approaching this the wrong way?

There is a follow up question to this, I originally updated this question but the update was sufficiently different to warrant a new question, here.

+2  A: 

periodically_call_remote() updates a div. It won't call your javascript function. I'm no javascript guru, but to solve your problem, you should do your own xmlhttp call. If I were you, I'd use prototype's ajax request

http://www.prototypejs.org/api/ajax/request

and use javascript's settimeout or setinterval to do the periodic polling

http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/

hope this helps cos actually I've encountered the same prb too =)

liangzan
A: 

The :update option should only list the div you want to update, NOT have Javascript that you want to evaluate.

The Rails helpers are still very good for this situation, there's no need to write much custom JS. If you wish to execute JS on return, an easy way would be to render an RJS template. If you wish to do it with pure HTML, simply render a view (or partial, or return directly from the render method with the HTML of the progress bar) and put the div of the progress bar in the :update option of the periodically_call_remote method.

Ian Terrell