Ajax loading bar function - javascript

I know there are a few post about this but they dont cover what i need to achieve.
I'm trying to get the youtubelike loading bar to work properly.
And i found this :
var data = [];
for (var i = 0; i < 100000; i++) {
var tmp = [];
for (var i = 0; i < 100000; i++) {
tmp[i] = 'hue';
}
data[i] = tmp;
};
xhr: function () {
var xhr = new window.XMLHttpRequest();
var percentComplete = 0; <--------------------------added this
$('.progress').removeClass('hide');<----------------and this
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
if (percentComplete === 1) {
$('.progress').addClass('hide');
}
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
}
}, false);
return xhr;
}
I have added 2 lines because it would only work once as the hidden value was not being removed after the completion. Also put the width back to 0. I also like the fact that it seams to be calculating the real percentage of the event.
This is working great. Howerver, i want to turn this into a function that can be called for all my ajax call like this:
$(document).ready(function () {
$("a").on("click", function (event) {
event.preventDefault();
var id = ($(this).attr("id"));
var container = ($(this).attr("data-container"));
var link = ($(this).attr("href"));
var text = ($(this).text());
var html = ($(this).html());
MY_LOADING_BAR_FUNCTION();<-----------------------------------Here i guess?
$.ajax({
url: 'ajax-php.php',
type: 'post',
data: { 'action': 'click', 'id': id, 'text': text, 'link': link, 'html': html },
success: function (data, status) {
if (container == '#formbox') {
$("#screen").addClass("visible");
}
$(container).html(data);
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
}); // end ajax call
}); // end on click
}); // en document ready
But i also ran across the Ajax setup that looks like this.
$.ajaxSetup({
beforeSend: function() {
},
complete : function() {
}
});
Right now i got it to work by putting the entire code of the xhr: function () inside my ajax call. But i dont want to do it every time.
So these are the 2 options i have found that could work but i cant get them to work the way i want. I try to make a MY_LOADING_BAR_FUNCTION() but i'm getting a deprecated error.
Can anyone tell me how to make this work please.
Thank you everyone!

It's late to reply, but its worth to share some knowledge, so others may get help from it.
You can extend jQuery AJAX XHR object as below.
jQuery.ajaxSettings.xhr = function ()
{
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress
console.log('percent uploaded: ' + (percentComplete * 100));
}
}, false);
//Download progress
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
console.log('percent downloaded: ' + (percentComplete * 100));
}
}, false);
return xhr;
}

Related

Progress bar with ajax and Jquery

i saw many examples - all looked pretty much the same to - make a progress bar (while uploading a file - until it finishes uploading)
so i tried this code -
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
if (percentComplete === 1) {
$('.progress').addClass('hide');
}
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
}
}, false);
return xhr;
},
type: 'POST',
url: "/echo/html",
data: data,
success: function (data) {}
});
ignore the url and the data - the example is on the xhr part
so when i tried to use this i saw that many people say that it no longer supported with jQuery 1.9.3+.
anybody has an idea how i can do it?

Find resultant of two asynchronous ajax request in xhr onprogress

I am trying to find images in ajax request response text and fetch the src url for using in another ajax request.
I need to know progress of loading each image and show the resultant of this progress in my progress bar.
But as you can see if image1 loaded 10%;
and image2 20%.
My result decreases from 20% to 10% .
My progress bar goes backward and then goes forward.
Any help?
or is this a good solution?
parseResult: function(result, navNumber) {
var self = this;
var imagesMatter = $(result).find('img');
var imagesLength = imagesMatter.length;
// if there is any image in ajax request then fetch imgs using ajax for show progress bar
if (imagesLength >= 1) {
var i = 0,
complete = 0,
temp = 1;
navigation.progress.fadeIn(50);
imagesMatter.each(function() {
var $this = $(this);
var URL = $this.attr('src');
$.ajax({
url: URL,
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = parseFloat(evt.loaded / evt.total).toFixed(1);
temp = complete + (percentComplete / imagesLength);
console.log(parseInt(temp * 100) + '%');
navigation.progress.html(parseInt(temp * 100) + '%');
}
}, false);
return xhr;
},
complete: function() {
complete = temp;
i++;
if (i == imagesLength) {
self.closeLoading(navNumber);
}
}
});
});
} else {
return;
}
}
Here I have removed complete variable of yours, as I can' understand what is the purpose of it, and added a local variable lastPercent for each request, which will remember it's last progress percent for the perticular image request, so on new update we will add new percent and remove old percents... I hope this logic is clear to you...
parseResult: function(result, navNumber) {
var self = this;
var showPercent;
var imagesMatter = $(result).find('img');
var imagesLength = imagesMatter.length;
// if there is any image in ajax request then fetch imgs using ajax for show progress bar
if (imagesLength >= 1) {
var i = 0,
temp = 1;
navigation.progress.fadeIn(50);
imagesMatter.each(function() {
var $this = $(this);
var URL = $this.attr('src');
var lastPercent = 0;
$.ajax({
url: URL,
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = parseFloat(evt.loaded / evt.total).toFixed(1);
temp = temp + (percentComplete / imagesLength) - lastPercent;
lastPercent = (percentComplete / imagesLength);
showPercent = temp/imagesLength;
console.log(parseInt(showPercent * 100) + '%');
navigation.progress.html(parseInt(showPercent * 100) + '%');
}
}, false);
return xhr;
},
complete: function() {
i++;
if (i == imagesLength) {
self.closeLoading(navNumber);
}
}
});
});
} else {
return;
}
}

What is causing "Uncaught TypeError: Illegal Invocation" in this code?

Google Chrome's console is telling me
Uncaught TypeError: Illegal Invocation
when the following function is invoked
$('#txtUploadFile').on('change', function (e) {
var files = e.target.files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
}
else
{
console.log("lengthComputable evaluated to false;")
}
}, false);
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
}
else
{
console.log("lengthComputable evaluated to false;")
}
}, false);
return xhr;
},
type: 'POST',
url: '#Url.Action("upload","FileUploadAsync")',
data: data,
success: function(data){
console.log("success!");
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
}
});
I've looked through StackOverflow posts on this issue and none of the causes relate to anything I can see in mine. I'm not sure if it matters, but I can post the HTML and the controller if that could be part of the problem.
You're missing two options for the $.ajax call, these
contentType: false,
processData: false,
Making it like this
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
} else {
console.log("lengthComputable evaluated to false;")
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
} else {
console.log("lengthComputable evaluated to false;")
}
}, false);
return xhr;
},
type: 'POST',
url: '#Url.Action("upload","FileUploadAsync")',
data: data,
contentType: false,
processData: false,
success: function (data) {
console.log("success!");
}
});
if you let jQuery process the files internally it throws an Illegal invocation error.

Multiple onprogress event handlers from xhr in loop

I'm currently trying to build an ajax image uploader and I have it working except for one important part.
For each separate file I upload I would like to update a progress bar for the file. Currently it only updates the last files progress bar.
$("#upload-btn").click(function() {
console.log("Click");
for (var i = 0; i < files.length; i++) {
var fd = new FormData();
fd.append("file", files[i]);
fd.append("__RequestVerificationToken", $("input[name='__RequestVerificationToken']").val());
var xhr = new XMLHttpRequest();
xhr.open('POST', "#Url.Action("AjaxUpload")", true);
var filename = files[i].name;
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
var progressbar = $('a[data-name="' + files[i].name + '"]').siblings(".progress").find(".progress-bar");
progressbar.css("width", percentComplete + "%");
}
};
xhr.onload = function () {
console.log(this.status);
if (this.status == 200) {
var resp = JSON.parse(this.response);
console.log('Server got:', resp);
};
};
xhr.send(fd);
}
});
As you may have guessed from the code, I'm pretty terrible at javascript... Any help is greatly appreciated.
You need to scope your file name in the progress callback, currently it will only use the last value of i. Replace where you set your onprogress handler with this code.
(function(filename) {
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
var progressbar = $('a[data-name="' + filename + '"]').siblings(".progress").find(".progress-bar");
progressbar.css("width", percentComplete + "%");
}
};
})(files[i].name);
You can do something like this. Set the additional parameters of xhr.upload
// Set custom properties
xhr.upload.targetFileName = fileName;
and then access it in progress handler like this
xhr.upload.onprogress = function (e) {
// Access custom properties.
var fileName = e.target.targetFileName;
}
More details here: https://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/ view-source:http://mozilla.pettay.fi/xhr_upload/xhr_file_upload_demo_with_speed.html

Backbone.js base64 video upload with progress bar

I have a script that sends a base64 video to the server via backbone/ajax:
video = new AccountVideo();
video.set({video: imageFile});
this.collection.create(video, {
// wait for return status from server
wait: true,
success: function(model, response) {
App.utils.notifyEnd('Video is queued for transcoding.');
accountVideoListView.render();
},
error: function(model, xhr) {
App.utils.notifyEnd(xhr.responseJSON.message, 'error');
}
});
I am trying to find away to create an upload progress bar similar to how this works, but within backbone entirely.
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.open("POST", "/api/accounts/videos");
ajax.send(imageFile);
function progressHandler(event){
var percent = (event.loaded / event.total) * 100;
console.log(percent);
} function completeHandler(event){
}
I tried:
var self = this;
xhr: function() {
var xhr = $.ajaxSettings.xhr();
xhr.onprogress = self.handleProgress;
return xhr;
}
handleProgress: function(evt){
var percentComplete = 0;
if (evt.lengthComputable) {
percentComplete = evt.loaded / evt.total;
}
console.log(Math.round(percentComplete * 100)+"%");
}
But it would only show a 0% after the video finished. I think I am close, just need a pointer. Thanks!
Ok, so I looked around and found out a little more about what's going on with the xhr: function.
Here is what is working
// add image model to collection
this.collection.create(video, {
// wait for return status from server
wait: true,
success: function(model, response) {
App.utils.notifyEnd('Video is queued for transcoding.');
accountVideoListView.render();
},
error: function(model, xhr) {
App.utils.notifyEnd(xhr.responseJSON.message, 'error');
},
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',showProgress, false);
} else {
console.log("Upload progress is not supported.");
}
return myXhr;
}
});
function showProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
console.log(percentComplete);
}
}

Categories

Resources