Hey I have a problem with sending two files in a queque. I don't have any idea how to do that when I select 2 files, 2 were uploaded at once, and the next 2 were waiting in queue. Now when I select 4 files, 2 are sent and the next two will not send. Please look in my code. Maybe you have an idea. What I must to do that make it work in function induction ?
(function() {
var imageType = /image.*/;
function uploadFile(file, percent_info, p_bar, licznik) {
var url = "server/index.php";
if (file[licznik].type.match(imageType)) {
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
if (percentLoaded < 100) {
percent_info[licznik].style.width = percentLoaded + "%";
}
}
});
xhr.upload.addEventListener("load", function(e) {
var percentLoaded = Math.round((e.loaded / e.total) * 100);
percent_info[licznik].style.width = percentLoaded + "%";
});
function ready() {
return function() {
if (xhr.readyState == 4 && xhr.status == 200) {
p_bar[licznik].classList.add('trans_completed');
if (licznik < file.length){
licznik++;
}
}
};
}
xhr.onreadystatechange = ready();
xhr.open("POST", url, true);
fd.append('uploaded_file', file[licznik]);
xhr.send(fd);
}
};
var uploadfiles = document.querySelector('#file-upload');
uploadfiles.addEventListener('change', function() {
var files = this.files;
var percent_info = document.querySelectorAll('.progress_bar:not(.trans_completed) .percent');
var p_bar = document.querySelectorAll('.progress_bar:not(.trans_completed)');
/* --- Upload files to server loop --- */
(function induction(files, percent_info, p_bar) {
counter_file = 0;
counter_file_2 = 1;
function caller() {
uploadFile(files, percent_info, p_bar, counter_file);
uploadFile(files, percent_info, p_bar, counter_file_2);
}
caller();
})(files, percent_info, p_bar);
});
})();
Related
I am trying to chunk a file and send to the server as follows
var fileselect = document.getElementById("file");
fileselect.addEventListener("change", FileSelectHandler, false);
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
}
function FileSelectHandler(e) {
FileDragHover(e);
var blob = e.target.files[0] || e.dataTransfer.files[0];
worker = new Worker("fileupload.js");
worker.postMessage(blob);
worker.onmessage = function(e) {
console.log(e);
};
}
fileupload.js
self.onmessage = function(e) {
const BYTES_PER_CHUNK = 1024 * 1024 * 32;
var blob = new Blob([e.data]),
start = 0,
index = 0,
slices = Math.ceil(blob.size / BYTES_PER_CHUNK),
slices2 = slices;
while (start < blob.size) {
end = start + BYTES_PER_CHUNK;
if (end > blob.size) end = blob.size;
uploadChunk(blob, index, start, end, slices, slices2);
start = end;
index++;
}
};
function uploadChunk(blob, index, start, end, slices, slices2) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
slices--;
if (slices == 0) {
var xhrMerge = new XMLHttpRequest();
xhrMerge.open("POST", "uploadlargefile/?a=merge&name=" + blob.name + "&slices=" + slices2);
xhrMerge.onload = function() {
self.close();
};
xhrMerge.send();
}
};
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) self.postMessage(Math.round(100 / e.total * e.loaded)); //this doesn't work o.O
};
var chunk = blob.slice(start, end);
xhr.open("POST", "uploadlargefile/?a=chunk&name=" + blob.name + "&index=" + index);
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=--------------------");
xhr.send(chunk);
}
PHP
print_r($_GET['name']); print_r($_FILES);die;
I am able to get the name of the file but not the file . Any suggestion what could be wrong
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;
}
}
I want to preload a bunch of images and show the progress bar in the same time.
At the moment the code works only with 1 image, here is it:
$progress = document.querySelector('#progress');
var url = 'https://placekitten.com/g/2000/2000';
var request = new XMLHttpRequest();
request.onprogress = onProgress;
request.onload = onComplete;
request.onerror = onError;
function onProgress(event) {
if (!event.lengthComputable) {
return;
}
var loaded = event.loaded;
var total = event.total;
var progress = (loaded / total).toFixed(2);
$progress.textContent = 'Loading... ' + parseInt(progress * 100) + ' %';
console.log(progress);
}
function onComplete(event) {
var $img = document.createElement('img');
$img.setAttribute('src', url);
$progress.appendChild($img);
console.log('complete', url);
}
function onError(event) {
console.log('error');
}
$progress.addEventListener('click', function() {
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send(null);
});
<div id="progress">Click me to load</div>
And here is the jsfiddle to test the code out: https://jsfiddle.net/q5d0osLr/
How can I make it work with more than one image?
Use an array to store each progress and create a function to load image and record the necessary information for you.
var $progress = document.querySelector('#progress');
var url = 'https://placekitten.com/g/';
var urls =
['https://i.imgur.com/7raUYR2.jpg', 'https://i.imgur.com/i8GSA1b.jpg', 'https://i.imgur.com/jGkaxEZ.jpg',
'http://i.imgur.com/cuS5DDv.jpg', 'https://i.imgur.com/bl5DOR0.jpg', 'http://i.imgur.com/TuFu2lK.jpg',
'https://i.imgur.com/qbwarWi.jpg', 'https://i.imgur.com/hJ9Ylph.gif', 'https://i.imgur.com/8KLbDxe.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Pleiades_large.jpg/1024px-Pleiades_large.jpg',
];
// Store all progress.
var allProgress = [];
var loadImage = function(url) {
// Get current index.
var idx = allProgress.length;
// Push a progress in array.
allProgress.push(0.0);
var onProgress = function(evt) {
if (!evt.lengthComputable) {
return;
}
var loaded = evt.loaded;
var total = evt.total;
var progress = (loaded / total);
allProgress[idx] = progress;
// Calculate the progress by sum then divide.
var sum = allProgress.reduce(function(sum, val) {
return sum + val;
});
sum /= allProgress.length;
sum = sum.toFixed(2);
$progress.textContent = 'Loading... ' + parseInt(sum * 100) + ' %';
console.log(progress, idx);
};
var onComplete = function(evt) {
var $img = document.createElement('img');
$img.setAttribute('src', url);
document.body.appendChild($img);
console.log('complete', url);
};
var onError = function(evt) {
// You may have to do something with progress.
console.log('error');
};
// Move the request in function. So each of them is independent.
var request = new XMLHttpRequest();
request.onprogress = onProgress;
request.onload = onComplete;
request.onerror = onError;
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send(null);
};
$progress.addEventListener('click', function() {
urls.forEach(function(url) {
loadImage(url);
});
});
img {
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="progress">Click me to load</div>
I've got a problem with a script that is used to upload one or more multipart/form-data files.
On my client's server, when I try to upload more than one file, I receive:
xhr.status error 500;
The first file is uploaded okay, but I can't upload more than 1 file. On my server, everything works fine - there is no error 500.
I have searched the web for help, but I could only find information about server problems, such as: can not accept POST, GET, OPTIONS...
But it's working with one file - and I'm stuck.
I tried to upload the files one by one, but then my progress bar is flashing like....
Here is my code:
$(document).ready( function() {
$(".errorNotice").hide();
});
var form = document.getElementById('upload-form');
var ident = document.getElementById('ident');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('submit');
var max = document.getElementById('max');
var formUrl = form.action;
function sleep(milliseconds) {
setTimeout(function(){ return true; }, milliseconds);
}
form.onsubmit = function(event) {
event.preventDefault();
uploadButton.innerHTML = 'Trwa ładowanie...';
$("#upload-form").fadeOut();
setTimeout(function() {
$("#progressBar").fadeIn();
}, 500);
var files = fileSelect.files;
var formData = new FormData();
if( files.length > max.value) {
if( max.value == 1) {
var text = max.value + ' zdjęcie';
}
else if( max.value >1 && max.value <= 4) {
var text = max.value + ' zdjęcia';
}
else {
var text = max.value + ' zdjęć';
}
$("#progressBar").find("p").html('Możesz dodać maksymalnie: ' + text);
setTimeout(function() {
$("#progressBar").hide();
$("#upload-form").fadeIn();
}, 5000);
return false;
}
if( files.length == 0 )
{
$("#progressBar").hide();
$("#upload-form").show();
}
formData.append('ident', ident.value);
formData.append('modules', 'true');
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file.type.match('image.*')) {
continue;
}
formData.append('objectPhoto[]', file, file.name);
formData.append(name, file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', formUrl , true);
xhr.upload.addEventListener("progress", function(e) {
if(e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
document.getElementById("bar").style.width = percentage + '%';
document.getElementById("percent").innerHTML = percentage + '%';
}
}, false);
xhr.onload = function () {
console.log(this.responseText);
if(this.responseText == "ok") {
document.getElementById("percent").innerHTML = "Zakończono";
document.getElementById("progressBar").style.display = "none";
document.getElementById("upload-form").style.display = "block";
} else {
$(".errorNotice").show();
$(".errorNotice .error-text").html(this.responseText);
}
if (xhr.status === 200) {
uploadButton.innerHTML = 'Wgraj';
} else {
$(".errorNotice").show();
$(".errorNotice .error-text").html("Wystąpił nieoczekiwany błąd o kodzie: " + xhr.status);
uploadButton.innerHTML = 'Wyślij';
}
};
xhr.send(formData);
return false;
};
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