Updating server-side progress on Rails application
-
02-07-2019 - |
Question
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.
Solution
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 =)
OTHER TIPS
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.