Reputation: 5152
I am trying to display the progress percentage when i upload a file and unzip it. I am using ruby-zip to unzip the file. While unzipping I increment the counter and store it in database. I have a form like
<% form_tag '/unzip', :multipart => true do %>
<%= file_field_tag "zipfile", :size => 12 %>
<button class="add_button" type="submit" value="Add"> Add </button>
<% end %>
<div class="progress">
</div>
In unzip
action there is everything that does unzipping and storing the value in database. Now, I would like to update the .progress div
every 2 seconds or so. First, I tried to make ajax call when the button is clicked and call another method that gets this progress. But I was not successful because, this simple code below was giving me error.
<script>
$(".add_button").click(function() {
$.ajax({
url: "/get_progress",
method: "POST"
})
})
</script>
In get_progress method, I just take out the value from the database like
def get_progress
@progress = Progress.last.value
respond_to do |format|
format.js
end
end
For simple checking purpose, I just do console.log("rendered")
in the get_progress.js.erb
. But this never gets called as there is error message before it. But, I checked and the ajax call is making request to get_progress
.
But the problem is, I am getting error in xhr.send((s.hasContent && s.data) || null)
in jquery1.6.3 line number 7948. I think I am getting this error because this page is redirected somewhere else during the ajax call and there is another request going on while I make the call as it is obvious that I have another action called when the form gets submitted.
When I print out the error on ajax call by doing:
error:function(xmlHTTPRequest, textStatus, errorThrown){
console.log(xmlHTTPRequest);
}
I am getting this:
Object {readyState = 0 ,status = 0 ,statusText = "error" }
I think my problem is similar to this question. But, the answer presented here did not solve my issue.
Is there any way I can solve this issue? I hope the question is clear!
Upvotes: 3
Views: 392
Reputation: 16659
This seems to work for me when I changed the ajax call from a post
to a get
.
View:
Progress:
<div id="progress">
</div>
<br />
<button class="add_button" type="submit" value="Add"> Add </button>
<script>
$(".add_button").click(function() {
$.ajax({
url: "/get_progress",
method: "get",
dataType: "script"
})
})
</script>
Controller:
def get_progress
@progress = Progress.last.value
respond_to do |format|
format.js
end
end
get_progress.js.erb:
$("#progress").text("<%= @progress.to_s %>");
Some obvious things to check:
P.S. To run it in loop:
function updateProgress() {
$.ajax({
url: "/get_progress",
method: "get",
dataType: "script"
});
}
// Set the function above to run every 2 seconds
var i = setInterval(updateProgress, 2000);
And update get_progress.js.erb:
$("#progress").text("<%= @progress.to_s %>");
var checkprogress = <%= @progress.to_i %>;
if (checkprogress == 100) {
// Stop the function running. Should add clearInterval to error handling of ajax also
clearInterval(i);
}
Edit
If there is some kind of conflict between the submit of the unzip action and retrieving the progress, I would recommend that you make the unzip submit asynchronous, using remotipart. Then change the form for unzip to:
<% form_tag '/unzip', :html => { :multipart => true }, :remote => true do %>
and add a create.js.erb
file with <%= remotipart_response do %>
as per the remotipart readme. I would still recommend that the get_progress ajax call is a get method.
Upvotes: 1