jQuery dnd file upload for multiple targets - javascript

I'm using jQuery dnd file upload plugin for a project. All example of dnd uploader use id as a selector. For multiple items they used different dropzone declaration.
How can I change the plugin setting for multiple dropzone where the selector will be a class or something else to grab multiple elements with a single dropzone initiation?

Since this is using jQuery, couldn't you use the standard jQuery multiple selector method? It would look like this:
$("#drop1, #drop2, #drop3").dropzone();
Or if you are trying to do a class, you would do this:
$(".drop_zone").dropzone();
This isn't tested, and I have never used this plugin. I'm just assuming this would work since it is based off jQuery.
Since that isn't working, try replacing the code for jquery.dnd-file-upload.js with the following:
(function ($) {
$.fn.dropzone = function (options) {
var opts = {};
var uploadFiles = function (files) {
$.fn.dropzone.newFilesDropped(); for (var i = 0; i < files.length; i++) {
var file = filesi?;
// create a new xhr object var xhr = new XMLHttpRequest(); var upload = xhr.upload; upload.fileIndex = i; upload.fileObj = file; upload.downloadStartTime = new Date().getTime(); upload.currentStart = upload.downloadStartTime; upload.currentProgress = 0; upload.startData = 0;
// add listeners upload.addEventListener("progress", progress, false);
xhr.onload = function (event) {
load(event, xhr);
};
xhr.open(opts.method, opts.url); xhr.setRequestHeader("Cache-Control", "no-cache"); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.setRequestHeader("X-File-Name", file.fileName); xhr.setRequestHeader("X-File-Size", file.fileSize); xhr.setRequestHeader("Content-Type", "multipart/form-data"); xhr.send(file);
$.fn.dropzone.uploadStarted(i, file);
}
};
var drop = function (event) {
var dt = event.dataTransfer; var files = dt.files;
event.preventDefault(); uploadFiles(files);
return false;
};
var log = function (logMsg) {
if (opts.printLogs) {
// console && console.log(logMsg);
}
};
// invoked when the input field has changed and new files have been dropped // or selected var change = function (event) {
event.preventDefault();
// get all files ... var files = this.files;
// ... and upload them uploadFiles(files);
};
var progress = function (event) {
if (event.lengthComputable) {
var percentage = Math.round((event.loaded 100) / event.total); if (this.currentProgress != percentage) {
// log(this.fileIndex + " --> " + percentage + "%");
this.currentProgress = percentage; $.fn.dropzone.fileUploadProgressUpdated(this.fileIndex, this.fileObj, this.currentProgress);
var elapsed = new Date().getTime(); var diffTime = elapsed - this.currentStart; if (diffTime >= opts.uploadRateRefreshTime) {
var diffData = event.loaded - this.startData; var speed = diffData / diffTime; // in KB/sec
$.fn.dropzone.fileUploadSpeedUpdated(this.fileIndex, this.fileObj, speed);
this.startData = event.loaded; this.currentStart = elapsed;
}
}
}
};
var load = function (event, xhr) {
var now = new Date().getTime(); var timeDiff = now - this.downloadStartTime; if (opts.onLoadComplete) {
opts.onLoadComplete(xhr.responseText);
} $.fn.dropzone.uploadFinished(this.fileIndex, this.fileObj, timeDiff); log("finished loading of file " + this.fileIndex);
};
var dragenter = function (event) {
event.stopPropagation(); event.preventDefault(); return false;
};
var dragover = function (event) {
event.stopPropagation(); event.preventDefault(); return false;
};
// Extend our default options with those provided. opts = $.extend({}, $.fn.dropzone.defaults, options);
var id = this.attr("id"); var dropzone = document.getElementById(id);
log("adding dnd-file-upload functionalities to element with id: " + id);
// hack for safari on windows: due to not supported drop/dragenter/dragover events we have to create a invisible <input type="file" /> tag instead if ($.client.browser == "Safari" && $.client.os == "Windows") {
var fileInput = $("<input>"); fileInput.attr({
type: "file"
}); fileInput.bind("change", change); fileInput.css({
'opacity': '0', 'width': '100%', 'height': '100%'
}); fileInput.attr("multiple", "multiple"); fileInput.click(function () {
return false;
}); this.append(fileInput);
} else {
dropzone.addEventListener("drop", drop, true); var jQueryDropzone = $("#" + id); jQueryDropzone.bind("dragenter", dragenter); jQueryDropzone.bind("dragover", dragover);
}
return this;
};
$.fn.dropzone.defaults = {
url: "", method: "POST", numConcurrentUploads: 3, printLogs: false, // update upload speed every second uploadRateRefreshTime: 1000
};
// invoked when new files are dropped $.fn.dropzone.newFilesDropped = function () { };
// invoked when the upload for given file has been started $.fn.dropzone.uploadStarted = function (fileIndex, file) { };
// invoked when the upload for given file has been finished $.fn.dropzone.uploadFinished = function (fileIndex, file, time) { };
// invoked when the progress for given file has changed $.fn.dropzone.fileUploadProgressUpdated = function (fileIndex, file,
newProgress) {
};
// invoked when the upload speed of given file has changed $.fn.dropzone.fileUploadSpeedUpdated = function (fileIndex, file,
KBperSecond) {
};
})(jQuery);
This was suggested by the user rik.leigh#gmail.com here http://code.google.com/p/dnd-file-upload/wiki/howto

Related

Dropzone.js not uploading files on IOS

I am using dropzone to upload files to a server. When the use adds files to the dropzone, they have the option to alter the name of the file. For example; instead of D6282238752Q82.png, the file will be saved as Dog.png .
This is my code:
<script type="text/javascript">
Dropzone.autoDiscover = false;
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
var myDropzone = new Dropzone('div#mydropzone', { // Make the whole body a dropzone
url: "/Upload.aspx?no=<%= Request.QueryString["no"] %>", // Set the url
parallelUploads: 10,
thumbnailWidth: 150,
thumbnailHeight: 80,
uploadMultiple: true,
previewTemplate: previewTemplate,
autoProcessQueue: false,
acceptedFiles: "image/*,application/pdf,.doc,.docx,.xls,.xlsx,.csv,.tsv,.ppt,.pptx,.pages,.odt,.rtf",
previewsContainer: "#previews", // Define the container to display the previews
clickable: [".fileinput-button", ".upload-drop-zone"], // Define the element that should be used as click trigger to select files.
init: function() {
var submitButton = document.querySelector("#submit-all")
myDropzone = this;
},
});
myDropzone.on("addedfile", function (file) {
// Hookup the start button
var filename = file.name;
var extension = filename.split('.').pop();
file.previewElement.querySelector("#txtNewFileName").value = filename.substr(0, filename.lastIndexOf('.'));
file.previewElement.querySelector("#txtFileExtension").innerHTML = filename.split('.').pop().toUpperCase();
var submitButton = document.querySelector("#submit-all")
submitButton.classList.remove("invisible");
submitButton.classList.add("visible");
});
// Update the total progress bar
myDropzone.on("totaluploadprogress", function (progress) {
document.querySelector("#total-progress .progress-bar").style.width = progress + "%";
});
myDropzone.on("sending", function (file, xhr, formData) {
// Show the total progress bar when upload starts
document.querySelector("#total-progress").style.opacity = "1";
var filename = file.name;
var extension = filename.split('.').pop();
var newFilename = file.previewElement.querySelector("#txtNewFileName").value + '.' + extension;
formData.append("newFileName", newFilename);
});
myDropzone.on("processing", function () {
myDropzone.options.autoProcessQueue = true;
});
// Hide the total progress bar when nothing's uploading anymore
myDropzone.on("queuecomplete", function (sending, progress) {
document.querySelector("#total-progress").style.opacity = "0";
});
myDropzone.on("success", function (progress, file) {
var submitButton = document.querySelector("#submit-all")
submitButton.classList.remove("visible");
submitButton.classList.add("invisible");
var refreshButton = document.getElementById("<%= btnRefresh.ClientID %>");
refreshButton.click();
});
myDropzone.on("removedfile", function (file) {
//post request to remove file from server
$.post("/Upload.aspx?no=<%= Request.QueryString["no"] %>&delete=" + file.newName);
var refreshButton = document.getElementById("<%= btnRefresh.UserID %>");
refreshButton.click();
});
myDropzone.on('dragover', function (e) {
this.className = 'upload-drop-zone drop';
return false;
})
$(document).on('click', '#submit-all', function (file) {
myDropzone.processQueue();
});
</script>
It works fine on Chrome, Edge and android, but not on Iphone or Ipad. I have tried to find an answer online, but to no avail.
I found an answer that helped me, in case anyone has the same problem.
I couldn't find a way to solve it in dropzone, so opted for C# instead. I used a $POST method to change the filenames.
$(document).on('click', '#submit-all', function (file) {
myDropzone.processQueue();
var newFilenames = [...document.querySelectorAll("#txtNewFileName")].map(sel => sel.value).join(',');
$.post("/Upload.aspx?no=<%= Request.QueryString["no"] %>&rename=" + newFilenames);//changeFileNames);
});
In Upload.aspx.cs I have the following code:
if (!String.IsNullOrEmpty(Request.QueryString["rename"]))
{
string renameF = Request.QueryString["rename"];
string[] renames = renameF.Split(',');
var di = new DirectoryInfo(fileArchivePath);
var filess = di.GetFiles().OrderByDescending(d => d.LastWriteTime).ToArray();
int count = 0;
foreach (string name in renames)
{
string inn = filess[count].FullName;
string ext = filess[count].Extension;
string ny = name + ext;
string inDir = Path.Combine(fileArchivePath, inn);
string nynavn = Path.Combine(fileArchivePath, ny);
if (File.Exists(inDir))
{
File.Copy(inDir, nynavn, true);
File.Delete(inDir);
}
count++;
}
return;
}
I already have code that uploads the files, but the additional Post method changes the existing filenames.

Calling data from JSON file using AJAX

I am trying to load some data from my JSON file using AJAX. The file is called external-file.json. Here is the code, it includes other parts that haven't got to do with the data loading.The part I'm not sure of begins in the getViaAjax funtion. I can't seem to find my error.
function flip(){
if(vlib_front.style.transform){
el.children[1].style.transform = "";
el.children[0].style.transform = "";
} else {
el.children[1].style.transform = "perspective(600px) rotateY(-180deg)";
el.children[0].style.transform = "perspective(600px) rotateY(0deg)";
}
}
var vlib_front = document.getElementById('front');
var el = document.getElementById('flip3D');
el.addEventListener('click', flip);
var word = null; var explanation = null;
var i=0;
function updateDiv(id, content) {
document.getElementById(id).innerHTML = content;
document.getElementById(id).innerHTML = content;
}
updateDiv('the-h',word[i]);
updateDiv('the-p',explanation[i])
function counter (index, step){
if (word[index+step] !== undefined) {
index+=step;
i=index;
updateDiv('the-h',word[index]);
updateDiv('the-p',explanation[index]);
}
}
var decos = document.getElementById('deco');
decos.addEventListener('click', function() {
counter(i,-1);
}, false);
var incos = document.getElementById('inco');
incos.addEventListener('click', function() {
counter(i,+1);
}, false);
function getViaAjax("external-file.json", callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", "external-file.json", true);
r.onload = function() {
if(this.status < 400 && this.status > 199) {
if(typeof callback === "function")
callback(JSON.parse(this.response));
} else {
console.log("err");// server reached but gave shitty status code}
};
}
r.onerror = function(err) {console.log("error Ajax.get "+url);console.log(err);}
r.send();
}
function yourLoadingFunction(jsonData) {
word = jsonData.words;
explanation = jsonData.explanation;
updateDiv('the-h',word[i]);
updateDiv('the-p',explanation[i])
// then call whatever it is to trigger the update within the page
}
getViaAjax("external-file.json", yourLoadingFunction)
As #light said, this:
function getViaAjax("external-file.json", callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", "external-file.json", true);
Should be:
function getViaAjax(url, callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", url, true);
I built up a quick sample that I can share that might help you isolate your issue. Stand this up in a local http-server of your choice and you should see JSON.parse(xhr.response) return a javascript array containing two objects.
There are two files
data.json
index.html
data.json
[{
"id":1,
"value":"foo"
},
{
"id":2,
"value":"bar"
}]
index.html
<html>
<head>
</head>
<body onload="so.getJsonStuffs()">
<h1>so.json-with-ajax</h1>
<script type="application/javascript">
var so = (function(){
function loadData(data){
var list = document.createElement("ul");
list.id = "data-list";
data.forEach(function(element){
var item = document.createElement("li");
var content = document.createTextNode(JSON.stringify(element));
item.appendChild(content);
list.appendChild(item);
});
document.body.appendChild(list);
}
var load = function()
{
console.log("Initializing xhr");
var xhr = new XMLHttpRequest();
xhr.onload = function(e){
console.log("response has returned");
if(xhr.status > 200
&& xhr.status < 400) {
var payload = JSON.parse(xhr.response);
console.log(payload);
loadData(payload);
}
}
var uri = "data.json";
console.log("opening resource request");
xhr.open("GET", uri, true);
xhr.send();
}
return {
getJsonStuffs : load
}
})();
</script>
</body>
</html>
Running will log two Javascript objects to the Dev Tools console as well as add a ul to the DOM containing a list item for every object inside the data.json array

building a voice recorder using html5 and javascript

I want to build a voice recorder using HTML5 same as one found in gitHub JSSoundecorder, but what I want is for the user to be able to choose the file format before recording the voice.I can do this using ffmpeg. In other words the user must be able to select the audio format by check box (mp3,wma,pcm) and in the background code, the .wav file usually created by the program instead of displaying it, it should be converted by the format selected then displayed in the new format.this is the ffmpeg code we can use ,but I don't know how to get the .wav audio file to convert it and show it.please if someone have ideas,or if can find demos I have been looking for weeks.this is the ffmpeg code:
var fileName;
var fileBuffer;
function timeToSeconds(time) {
var parts = time.split(":");
return parseFloat(parts[0]) * 60 * 60 + parseFloat(parts[1]) * 60 + parseFloat(parts[2]) + parseFloat("0." + parts[3]);
}
// create ffmpeg worker
function getFFMPEGWorker() {
// regexps for extracting time from ffmpeg logs
var durationRegexp = /Duration: (.*?), /
var timeRegexp = /time=(.*?) /;
var duration;
var ffmpegWorker = new Worker('worker.js');
var durationLine;
ffmpegWorker.addEventListener('message', function(event) {
var message = event.data;
console.log(message.type);
if (message.type === "ready" && window.File && window.FileList && window.FileReader) {
// script loaded, hide loader
$('#loading').hide();
} else if (message.type == "stdout") {
console.log(message.data);
} else if (message.type == "stderr") {
console.log(message.data);
// try to extract duration
if (durationRegexp.exec(message.data)) {
duration = timeToSeconds(durationRegexp.exec(message.data)[1]);
}
// try to extract time
if (timeRegexp.exec(message.data)) {
var time = timeToSeconds(timeRegexp.exec(message.data)[1]);
if (duration) {
$("#progress").text("Progress: " + Math.floor(time / duration * 100) + "%");
$("#progress").show();
}
}
} else if (message.type == "done") {
var code = message.data.code;
console.log(message.data);
var outFileNames = Object.keys(message.data.outputFiles);
console.log(outFileNames);
if (code == 0 && outFileNames.length) {
var outFileName = outFileNames[0];
var outFileBuffer = message.data.outputFiles[outFileName];
var src = window.URL.createObjectURL(new Blob([outFileBuffer]));
$("#downloadLink").attr('href', src);
$("#download").show();
} else {
$("#error").show();
}
$("#converting").hide();
$("#progress").hide();
}
}, false);
return ffmpegWorker;
}
// create ffmpeg worker
var ffmpegWorker = getFFMPEGWorker();
var ffmpegRunning = false;
$('#convert').click(function() {
// terminate existing worker
if (ffmpegRunning) {
ffmpegWorker.terminate();
ffmpegWorker = getFFMPEGWorker();
}
ffmpegRunning = true;
// display converting animation
$("#converting").show();
$("#error").hide();
// hide download div
$("#download").hide();
// change download file name
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
var outFileName = fileName.substr(0, fileName.lastIndexOf('.')) + "." + getOutFormat();
$("#downloadLink").attr("download", outFileName);
$("#downloadLink").text(outFileName);
var arguments = [];
arguments.push("-i");
arguments.push(fileName);
arguments.push("-b:a");
arguments.push(getBitrate());
switch (getOutFormat()) {
case "mp3":
arguments.push("-acodec");
arguments.push("libmp3lame");
arguments.push("out.mp3");
break;
case "wma":
arguments.push("-acodec");
arguments.push("wmav1");
arguments.push("out.asf");
break;
case "pcm":
arguments.push("-f");
arguments.push("s16le");
arguments.push("-acodec");
arguments.push("pcm_s16le");
arguments.push("out.pcm");
}
ffmpegWorker.postMessage({
type: "command",
arguments: arguments,
files: [
{
"name": fileName,
"buffer": fileBuffer
}
]
});
});
function getOutFormat() {
return $('input[name=format]:checked').val();
}
function getBitrate() {
return $('input[name=bitrate]:checked').val();
}
// disable conversion at start
$('#convert').attr('disabled', 'true');
function readInputFile(file) {
// disable conversion for the time of file loading
$('#convert').attr('disabled', 'true');
// load file content
var reader = new FileReader();
reader.onload = function(e) {
$('#convert').removeAttr('disabled');
fileName = file.name;
console.log(fileName);
fileBuffer = e.target.result;
}
reader.readAsArrayBuffer(file);
}
// reset file selector at start
function resetInputFile() {
$("#inFile").wrap('<form>').closest('form').get(0).reset();
$("#inFile").unwrap();
}
resetInputFile();
function handleFileSelect(event) {
var files = event.target.files; // FileList object
console.log(files);
// files is a FileList of File objects. display first file name
file = files[0];
console.log(file);
if (file) {
$("#drop").text("Drop file here");
readInputFile(file);
}
}
// setup input file listeners
document.getElementById('inFile').addEventListener('change', handleFileSelect, false);

JavaScript loading progress of an image

Is there a way in JS to get the progress of a loading image while the image is being loaded?
I want to use the new Progress tag of HTML5 to show the progress of loading images.
I wish there was something like:
var someImage = new Image()
someImage.onloadprogress = function(e) { progressBar.value = e.loaded / e.total };
someImage.src = "image.jpg";
With this, you add 2 new functions on the Image() object:
Image.prototype.load = function(url){
var thisImg = this;
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET', url,true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
var blob = new Blob([this.response]);
thisImg.src = window.URL.createObjectURL(blob);
};
xmlHTTP.onprogress = function(e) {
thisImg.completedPercentage = parseInt((e.loaded / e.total) * 100);
};
xmlHTTP.onloadstart = function() {
thisImg.completedPercentage = 0;
};
xmlHTTP.send();
};
Image.prototype.completedPercentage = 0;
And here you use the load function and append the image on a div.
var img = new Image();
img.load("url");
document.getElementById("myDiv").appendChild(img);
During the loading state you can check the progress percentage using img.completedPercentage.
Sebastian's answer is excellent, the best I've seen to this question. There are, however, a few possible improvements. I use his code modified like this:
Image.prototype.load = function( url, callback ) {
var thisImg = this,
xmlHTTP = new XMLHttpRequest();
thisImg.completedPercentage = 0;
xmlHTTP.open( 'GET', url , true );
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function( e ) {
var h = xmlHTTP.getAllResponseHeaders(),
m = h.match( /^Content-Type\:\s*(.*?)$/mi ),
mimeType = m[ 1 ] || 'image/png';
// Remove your progress bar or whatever here. Load is done.
var blob = new Blob( [ this.response ], { type: mimeType } );
thisImg.src = window.URL.createObjectURL( blob );
if ( callback ) callback( this );
};
xmlHTTP.onprogress = function( e ) {
if ( e.lengthComputable )
thisImg.completedPercentage = parseInt( ( e.loaded / e.total ) * 100 );
// Update your progress bar here. Make sure to check if the progress value
// has changed to avoid spamming the DOM.
// Something like:
// if ( prevValue != thisImage completedPercentage ) display_progress();
};
xmlHTTP.onloadstart = function() {
// Display your progress bar here, starting at 0
thisImg.completedPercentage = 0;
};
xmlHTTP.onloadend = function() {
// You can also remove your progress bar here, if you like.
thisImg.completedPercentage = 100;
}
xmlHTTP.send();
};
Mainly I added a mime-type and some minor details. Use as Sebastian describes. Works well.
Just to add to the improvements, I've modified Julian's answer (which in turn modified Sebastian's). I've moved the logic to a function instead of modifying the Image object. This function returns a Promise that resolves with the URL object, which only needs to be inserted as the src attribute of an image tag.
/**
* Loads an image with progress callback.
*
* The `onprogress` callback will be called by XMLHttpRequest's onprogress
* event, and will receive the loading progress ratio as an whole number.
* However, if it's not possible to compute the progress ratio, `onprogress`
* will be called only once passing -1 as progress value. This is useful to,
* for example, change the progress animation to an undefined animation.
*
* #param {string} imageUrl The image to load
* #param {Function} onprogress
* #return {Promise}
*/
function loadImage(imageUrl, onprogress) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
var notifiedNotComputable = false;
xhr.open('GET', imageUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onprogress = function(ev) {
if (ev.lengthComputable) {
onprogress(parseInt((ev.loaded / ev.total) * 100));
} else {
if (!notifiedNotComputable) {
notifiedNotComputable = true;
onprogress(-1);
}
}
}
xhr.onloadend = function() {
if (!xhr.status.toString().match(/^2/)) {
reject(xhr);
} else {
if (!notifiedNotComputable) {
onprogress(100);
}
var options = {}
var headers = xhr.getAllResponseHeaders();
var m = headers.match(/^Content-Type\:\s*(.*?)$/mi);
if (m && m[1]) {
options.type = m[1];
}
var blob = new Blob([this.response], options);
resolve(window.URL.createObjectURL(blob));
}
}
xhr.send();
});
}
/*****************
* Example usage
*/
var imgContainer = document.getElementById('imgcont');
var progressBar = document.getElementById('progress');
var imageUrl = 'https://placekitten.com/g/2000/2000';
loadImage(imageUrl, (ratio) => {
if (ratio == -1) {
// Ratio not computable. Let's make this bar an undefined one.
// Remember that since ratio isn't computable, calling this function
// makes no further sense, so it won't be called again.
progressBar.removeAttribute('value');
} else {
// We have progress ratio; update the bar.
progressBar.value = ratio;
}
})
.then(imgSrc => {
// Loading successfuly complete; set the image and probably do other stuff.
imgContainer.src = imgSrc;
}, xhr => {
// An error occured. We have the XHR object to see what happened.
});
<progress id="progress" value="0" max="100" style="width: 100%;"></progress>
<img id="imgcont" />
Actually, in latest chrome you can use 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>
Here is a small update of the code of Julian Jensen in order to be able to draw the image in a Canvas after it is loaded :
xmlHTTP.onload = function( e ) {
var h = xmlHTTP.getAllResponseHeaders(),
m = h.match( /^Content-Type\:\s*(.*?)$/mi ),
mimeType = m[ 1 ] || 'image/png';
// Remove your progress bar or whatever here. Load is done.
var blob = new Blob( [ this.response ], { type: mimeType } );
thisImg.src = window.URL.createObjectURL( blob );
thisImg.onload = function()
{
if ( callback ) callback( this );
};
};
for xmlhttpreq v2 check, use:
var xmlHTTP = new XMLHttpRequest();
if ('onprogress' in xmlHTTP) {
// supported
} else {
// isn't supported
}
If you want to process your loaded image, than you have to add one more function, because
thisImg.src = window.URL.createObjectURL(blob)
just starts to process the image as a thread.
You have to add a new a function to the body of load prototype, like
this.onload = function(e)
{
var canvas = document.createElement('canvas')
canvas.width = this.width
canvas.height = this.height
canvas.getContext('2d').drawImage(this, 0, 0)
}
This make me headache to realize :)

How to pass additional parameters to javascript event object?

I am using HTML 5 FileReader to read more that one file asynchronously.
I would like to keep track of loading of individual files as more that one files can be added at once.
Now i created div with background 0% for each image, but i am not clear about how to pass this division's id or reference in the onprogress event so that i can track progress and update the div content dynamically.
In simple terms let me know about how to ensure that i am updating the correct progress control associated with the file, when multiple files are uploaded simultaneously? I am not getting my JS right.
var up_file = document.getElementById('multiple_file');
if(up_file.files)
{
for(var x=0; x <up_file.files.length; x++)
{
//console.log(up_file.files.length);
var file = up_file.files[x];
var loadingDiv = document.createElement("div");
var container = document.getElementById('loading_container');
loadingDiv.className = "loading";
loadingDiv.id ="loading_" + x;
loadingDiv.innerHTML = '0%';
container.appendChild(loadingDiv);
var reader = new FileReader();
reader.onprogress = function (evt) {
if (evt.lengthComputable) {
console.dir(evt);
// evt.loaded and evt.total are ProgressEvent properties
var loaded = (evt.loaded / evt.total);
if (loaded < 1) {
console.log(loaded);
}
}
}
var img = document.createElement("img");
img.className = "hide";
reader.onload = (function(aimg) {
return function(e) {
LIB.addEvent(aimg, "load", function(){
var scale = 1;
scale = aimg.width / 200;
aimg.width = aimg.width / scale;
aimg.className = "show";
}, false);
aimg.src = e.target.result;
var li = document.createElement("li");
li.appendChild(aimg);
document.getElementById('img_packet').appendChild(li);
};
})(img);
reader.readAsDataURL(file);
}
}
loadingDiv is still visible inside the onprogress function as a closure is formed. The problem is that it's in a loop, so by the time onprogress is called, loadingDiv will probably have been assigned a new value.
To get around this you can use an extra closure to take a copy of the current value of loadingDiv:
reader.onprogress= function(myloadingdiv) {
return function(evt) {
if (evt.lengthComputable)
myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
};
}(loadingDiv);
In ECMAScript Fifth Edition, the bind() method will does this for you more cleanly:
reader.onprogress= function(myloadingdiv, evt) {
if (evt.lengthComputable)
myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
}.bind(loadingDiv);
For browsers that don't support bind() yet, you can patch in an implementation thus:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
if (arguments.length<=1) {
return function() {
return that.apply(owner, arguments);
};
} else {
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
};
}
};
}

Categories