I am trying to create a file upload with progress-bar with the help of HTML5. trying to create multiple file-upload. Below is my code. Inside handleFiles function i have one alert statement and its returning 'undefined'. Can anyone help me here...
$('#photoimg').change(function()
{
handleFiles(this.files); alert('got it');
var $fileUpload = $("#photoimg");
if (parseInt($fileUpload.get(0).files.length)>$('#galCnt').val())
{
alert("Maximum of 5 images allowed to upload. Only "+$('#galCnt').val()+" left");
return false;
}
//var formData = new FormData($('#imageform')[0]);
fd = collectFormData();
// Attach the files.
for (var i = 0, ie = PENDING_FILES.length; i < ie; i++) {
// Collect the other form data.
fd.append("file", PENDING_FILES[i]);
}
// Inform the back-end that we're doing this over ajax.
fd.append("__ajax", "true");
$("#imageloadstatus").show();
//$("#imageloadbutton").hide();
var $progressBar = $("#progress-bar");
$progressBar.css({"width": "0%"});
var xhr = $.ajax({
xhr:function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener("progress", function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// Set the progress bar.
$progressBar.css({"width": percent + "%"});
$progressBar.text(percent + "%");
$("#loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
}, false)
}
return xhrobj;
},
url: SITE_URL+'/index/ajax',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
$progressBar.css({"width": "100%"});
$("#imageloadstatus").hide();
$('#preview').html(returndata);
}
});
});
var PENDING_FILES = [];
function collectFormData() {
// Go through all the form fields and collect their names/values.
var fd = new FormData();
$("#imageform :input").each(function() {
var $this = $(this);
var name = $this.attr("name");
var type = $this.attr("type") || "";
var value = $this.val();
// No name = no care.
if (name === undefined) {
return;
}
// Skip the file upload box for now.
if (type === "file") {
return;
}
// Checkboxes? Only add their value if they're checked.
if (type === "checkbox" || type === "radio") {
if (!$this.is(":checked")) {
return;
}
}
fd.append(name, value);
});
return fd;
}
function handleFiles(files) {
// Add them to the pending files list.
for (var i = 1; i <= files.length; i++)
{
alert(files[i]);
PENDING_FILES.push(files[i]);
}
}
Related
There is a script that processes lines from a text file and sends it to the server. The server, meanwhile, returns a response and fills in the required information.
The problem is that when you try to download a file with about a million entries, the browser freezes and takes a very long time to process.
Is it possible to make this process without browser delays?
document.getElementById('file').onchange = function() {
$('#uploader-after').show();
$('#uploader-before').hide();
$("#file").prop('disabled', true);
var o_time = performance.now();
$('o_total').text("");
$('o_errors').text("");
$('o_time').text("");
var file = this.files[0];
var count = 1;
var errorCount = 0;
$('.file-name').text(file.name);
var reader = new FileReader(file);
reader.onload = function(progressEvent) {
var lines = this.result.split('\n');
$('#find-count').text(lines.length);
for(var line = 0; line < lines.length; line++) {
//setTimeout( function() { // i try this, but dont work
jQuery.ajax({
'async': true,
'global': false,
'type': "POST",
'url': 'getFile.php',
'data': { url: lines[line] },
'dataType': "json",
'success': function(data) {
var answer = data.answer ? data.answer : "";
var id = data.id ? data.id : "";
$('#proc-count').text(count);
var proc = Math.round(count / lines.length * 100);
$('proc').text(proc);
$("#pg-bar-line").css("width", proc + "%");
count++;
if(id == "") {
errorCount++;
}
$('o_total').text(count - 1);
$('o_errors').text(errorCount);
scannert.DataTable().row.add([id, data.inputURL, answer]).draw(false);
if(count === lines.length) {
o_time = performance.now() - o_time;
$('o_time').text(msToTime(o_time));
$('.otchet').show();
$('#uploader-after').hide();
$('#uploader-before').show();
$("#file").prop('disabled', false);
}
},
'error': function() {
count++;
}
});
//}, 5);
}
};
reader.readAsText(file);
};
Ill try setTimeout, but it doesnt work -_-
I have a file upload page that uses ajax to show a progress bar and has a drag and drop feature (global.js and upload.js). But the progress bar and the drag and drop does not work. I get a Uncaught Reference error app not definded in my global.js. However, I have app defined in upload.js. Why does it complain about app not being defined? Thank you.
// global.js
(function() {
"use strict";
var dropZone = document.getElementById('drop-zone');
var barFill = document.getElementById('bar-fill');
var barFillText = document.getElementById('bar-fill-text');
var uploadsFinished = document.getElementById('uploads-finished');
var startUpload = function(files) {
app.uploader({
files: files,
progressBar: barFill,
progressText: barFillText,
processor: 'upload.php',
finished: function(data) {
var x;
var uploadedElement;
var uploadedAnchor;
var uploadedStatus;
var currFile;
for(x = 0; x < data.length; x = x + 1) {
currFile = data[x];
uploadedElement = document.createElement('div');
uploadedElement.className = 'upload-console-upload';
uploadedAnchor = document.createElement('a');
uploadedAnchor.textContent = currFile.name;
if(currFile.uploaded) {
uploadedAnchor.href = 'uploads/' + currFile.file;
}
uploadedStatus = document.createElement('span');
uploadedStatus.textContent = currFile.uploaded ? 'Uploaded' : 'Failed';
uploadedElement.appendChild(uploadedAnchor);
uploadedElement.appendChild(uploadedStatus);
uploadsFinished.appendChild(uploadedElement);
}
uploadsFinished.className = '';
},
error: function() {
console.log('There was an error');
}
});
};
// Standard form upload
document.getElementById('standard-upload').addEventListener('click', function(e) {
var standardUploadFiles = document.getElementById('standard-upload-files').files;
e.preventDefault();
startUpload(standardUploadFiles);
});
// Drop functionality
dropZone.ondrop = function(e) {
e.preventDefault();
this.className = 'upload-console-drop';
startUpload(e.dataTransfer.files);
};
dropZone.ondragover = function() {
this.className = 'upload-console-drop drop';
return false;
};
dropZone.ondragleave = function() {
this.className = 'upload-console-drop';
return false;
};
}());
// upload.js
var app = app || {};
(function(o) {
"use strict";
// Private methods
var ajax, getFormData, setProgress;
ajax = function(data) {
var xmlhttp = new XMLHttpRequest();
var uploaded;
xmlhttp.addEventListener('readystatechange', function() {
if(this.readyState === 4) {
if(this.status === 200) {
uploaded = JSON.parse(this.response);
if(typeof o.options.finished === 'function') {
o.options.finished(uploaded);
}
} else {
if(typeof o.options.error === 'function') {
o.options.error();
}
}
}
});
xmlhttp.upload.addEventListener('progress', function(e) {
var percent;
if(e.lengthComputable === true) {
percent = Math.round((event.loaded / event.total) * 100);
setProgress(percent);
}
});
xmlhttp.open('post', o.options.processor);
xmlhttp.send(data);
};
getFormData = function(source) {
var data = new FormData();
var i;
for(i = 0; i < source.length; i = i + 1) {
data.append('files[]', source[i]);
}
return data;
};
setProgress = function(value) {
if(o.options.progressBar !== undefined) {
o.options.progressBar.style.width = value ? value + '%' : 0;
}
if(o.options.progressText !== undefined) {
o.options.progressText.textContent = value ? value + '%' : '';
}
};
o.uploader = function(options) {
o.options = options;
if(o.options.files !== undefined) {
ajax(getFormData(o.options.files));
}
};
}(app));
The variable app is define inside the upload.js file. I thinks you should just load Upload.js before global.js
<script src="/javascripts/upload.js" type="text/javascript"></script>
<script src="/javascripts/global.js" type="text/javascript"></script>
The code below submits file on drop and will call ajaxat the same time but I tried changing it to a way where user can drop files after files and submit it at once.
I wrapped the function that sends file to ajaxwith on click but it is still sending file one by one. Why?
function handleFileUpload(files, obj) {
for (var i = 0; i < files.length; i++) {
var fd = new FormData();
fd.append('file', files[i]);
var status = new createStatusbar(obj); //Using this we can set progress.
status.setFileNameSize(files[i].name, files[i].size);
}
var submit = $("#submit-button-id");
submit.on('click', function(e) {
e.preventDefault();
alert("clicked nest!")
sendFileToServer(fd, status);
});
}
And here is the Web API ajaxcall function:
function sendFileToServer(formData, status) {
var uploadURL = _config.UploadPrismaTemplates;
var extraData = {}; //Extra Data.
var jqXHR = $.ajax({
xhr: function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//Set progress
status.setProgress(percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: "POST",
contentType: false, //not to set any content header
processData: false, //not to process data
cache: false,
data: formData,
success: function(data) {
status.setProgress(100);
//$("#status1").append("File upload Done<br>");
alert("set progress success");
},
error: function(xhr, status, error) {
alert(error);
}
});
status.setAbort(jqXHR);
} /*send file to server ends here*/
Here I fixed it ! It will only submit files if clicked.
$(document).ready(function(){
var drop = $('#drag-and-drop-zone');
var uploadBtn = $('#submit-button-id');
drop.on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
$(this).css('border', '2px solid #0B85A1');
});
drop.on('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
});
var rowCount = 0;
function createStatusbar(drop) {
rowCount++;
var row = "odd";
if (rowCount % 2 == 0) row = "even";
this.statusbar = $("<div class='statusbar " + row + "'></div>");
this.filename = $("<div class='filename'></div>").appendTo(this.statusbar);
this.size = $("<div class='filesize'></div>").appendTo(this.statusbar);
this.progressBar = $("<div class='progressBar'><div></div></div>").appendTo(this.statusbar);
this.abort = $("<div class='abort'>Abort</div>").appendTo(this.statusbar);
$('#display-status-id').append(this.statusbar);
this.setFileNameSize = function (name, size) {
var sizeStr = "";
var sizeKB = size / 1024;
if (parseInt(sizeKB) > 1024) {
var sizeMB = sizeKB / 1024;
sizeStr = sizeMB.toFixed(2) + " MB";
}
else {
sizeStr = sizeKB.toFixed(2) + " KB";
}
this.filename.html(name);
this.size.html(sizeStr);
}
this.setProgress = function (progress) {
var progressBarWidth = progress * this.progressBar.width() / 100;
this.progressBar.find('div').animate({ width: progressBarWidth }, 10).html(progress + "% ");
if (parseInt(progress) >= 100) {
this.abort.hide();
}
}
this.setAbort = function (jqxhr) {
var sb = this.statusbar;
this.abort.click(function () {
jqxhr.abort();
sb.hide();
});
}
}
/*****************************************/
drop.on('drop', function (e) {
$(this).css('border', '2px dotted #0B85A1');
e.preventDefault();
var files = e.originalEvent.dataTransfer.files;
if (!files) return;
console.log("drop:", drop);
for (var i = 0; i < files.length; i++) {
var status = new createStatusbar(drop);
status.setFileNameSize(files[i].name, files[i].size);
}
uploadBtn.on('click', function (e) {
var fd = new FormData();
for (var i = 0; i < files.length; i++)
{
fd.append(files[i].name, files[i]);
}
sendFiletoServer(fd);
});
function sendFiletoServer(formData) {
var uploadURL = "";
var extraData = {};
var jqXHR = $.ajax({
xhr: function () {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
Call event.preventDefault() at dragover event of droppable element, use a <button> element for user to click when they want to upload the FormData() object containing the files that they have dropped.
var drop = document.getElementById("drop");
var button = document.getElementById("upload");
var fd = new FormData();
drop.ondragover = function(e) {
e.preventDefault();
}
drop.ondrop = function(e) {
e.preventDefault();
if (e.dataTransfer.types[0] === "Files") {
var file = e.dataTransfer.files[0];
fd.append("files[]", file, file.name);
}
}
button.onclick = function(e) {
console.log([...fd]);
// do ajax stuff with `fd` here
// delete items in `fd` when ajax stuff completes
for (let [key, prop] of [...fd]) {
fd.delete(key)
}
console.log([...fd]);
}
#drop {
width: 300px;
height: 200px;
border: 2px dotted green;
text-align: center;
}
<div id="drop">Drop files</div>
<button id="upload">Upload</button>
I've created a dynamic upload and I want to send each blob to server after the images are cropped.
The problem is that it's sent only the last append and I don't know why.
var g = 0;
for(var j = 1;j <= boxno;j++) //boxno = 4 pics (I can have as much as I want)
{
input = $("#input"+j);
if(input.val().length !== 0)//check if input has any values
{
pcanvas = $("#pcanvas"+j)[0];
context = pcanvas.getContext("2d");
formData = new FormData($(this)[0]);
var blob = dataURLtoBlob(pcanvas.toDataURL('image/png'));
formData.append("pcanvas_"+g+"[]", blob);
g++;
}
}
var info = {
userid:userId,
username:userName,
picNr: g
}
formData.append("info[]", info["userid"]);
formData.append("info[]", info["username"]);
formData.append("info[]", info["picNr"]);
$.ajax({
url: "/send.php",
type: "POST",
data: formData,
contentType: false,
cache: false,
processData: false,
success: function(data) {
console.log(data);
},
error: function(data) {
console.log("error");
},
complete: function(data) {}
});
function dataURLtoBlob(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], {
type: contentType
});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {
type: contentType
});
}
Now if I send using this method is sent only "pcanvas3", the last loop. But If I put $.ajax inside the loop is working, but I don't want this, because I want to add into my db and is adding 4 times the same results (also I create new folder for a specific upload, so if I add inside the loop $.ajax it creates 4 folders)
Here is my php.
$id = $_POST['info'][0];
$username = $_POST['info'][1];
$picNr = $_POST['info'][2];
$shuffledid = str_shuffle($id);
$uniqueid = $id.$shuffledid;
$path = $_SERVER['DOCUMENT_ROOT'].'/_user/_tests/en/'.$uniqueid;
if(!file_exists($path))
{
mkdir($path,0755);
}
for($g = 0; $g <= $picNr; $g++)
{
$virtualbg = imagecreatetruecolor(400,410);
$tmp_file = $_FILES['pcanvas_'.$g]['tmp_name'][0];
$pic = imagecreatefrompng($tmp_file);
list($width,$height,$type) = getimagesize($tmp_file);
imagecopyresampled($virtualbg,$pic, 0,0,0,0, 400,410,$width,$height);
imagejpeg($virtualbg,$path.'/pic_'.$g.'.jpg');
imagedestroy($pic);
imagedestroy($virtualbg);
}
As you can see I'm passing through each "pcanvas_0,1,2,3,4" but only the last one it gets the tmp_files.
What I'm doing it wrong? I think the problem is on my append. I've tried to append something else to the formData("pcanvas.. and it works but my blob is not appended.
Thank you!
How to change the filename for the upload to id+filename?
Example:
I have the id in a javascript variable item_id.
Is there a chance to add data on data.append and use this in the "upload.php"?
I want that the file name have instead of time and date the prefix id. Example id = 00002, file name = "picturewhatever.jpg".
The to be uploaded file should be "00002PictureWhatever.jpg"
<div id="mulitplefileuploader" title="">
<br>
Upload
</div>
<div id="status"></div>
<script>
$(document).ready(function() {
var settings = {
url: "upload.php",
method: "POST",
allowedTypes:"jpg,png,gif",
fileName: "myfile",
multiple: true,
onSuccess:function(files,data,xhr) {
$("#status").html("<font color='green'>Upload successful</font>");
},
onError: function(files,status,errMsg) {
$("#status").html("<font color='red'>Upload failed</font>");
}
}
$("#mulitplefileuploader").uploadFile(settings);
});
</script>
</div>
File: multifileuploader.js
function multiUploader(config){
this.config = config;
this.items = "";
this.all = []
var self = this;
multiUploader.prototype._init = function(){
if (window.File &&
window.FileReader &&
window.FileList &&
window.Blob) {
var inputId = $("#"+this.config.form).find("input[type='file']").eq(0).attr("id");
document.getElementById(inputId).addEventListener("change", this._read, false);
document.getElementById(this.config.dragArea).addEventListener("dragover", function(e){ e.stopPropagation(); e.preventDefault(); }, false);
document.getElementById(this.config.dragArea).addEventListener("drop", this._dropFiles, false);
document.getElementById(this.config.form).addEventListener("submit", this._submit, false);
} else
console.log("Browser supports failed");
}
multiUploader.prototype._submit = function(e){
e.stopPropagation(); e.preventDefault();
self._startUpload();
}
multiUploader.prototype._preview = function(data){
this.items = data;
if(this.items.length > 0){
var html = "";
var uId = "";
for(var i = 0; i<this.items.length; i++){
uId = this.items[i].name._unique();
var sampleIcon = '<img src="images/image.png" />';
var errorClass = "";
if(typeof this.items[i] != undefined){
if(self._validate(this.items[i].type) <= 0) {
sampleIcon = '<img src="images/unknown.png" />';
errorClass =" invalid";
}
html += '<div class="dfiles'+errorClass+'" rel="'+uId+'"><h5>'+sampleIcon+this.items[i].name+'</h5><div id="'+uId+'" class="progress" style="display:none;"><img src="images/ajax-loader.gif" /></div></div>';
}
}
$("#dragAndDropFiles").append(html);
}
}
multiUploader.prototype._read = function(evt){
if(evt.target.files){
self._preview(evt.target.files);
self.all.push(evt.target.files);
} else
console.log("Failed file reading");
}
multiUploader.prototype._validate = function(format){
var arr = this.config.support.split(",");
return arr.indexOf(format);
}
multiUploader.prototype._dropFiles = function(e){
e.stopPropagation(); e.preventDefault();
self._preview(e.dataTransfer.files);
self.all.push(e.dataTransfer.files);
}
multiUploader.prototype._uploader = function(file,f){
if(typeof file[f] != undefined && self._validate(file[f].type) > 0){
var data = new FormData();
var ids = file[f].name._unique();
data.append('file',file[f]);
data.append('index',ids);
$(".dfiles[rel='"+ids+"']").find(".progress").show();
$.ajax({
type:"POST",
url:this.config.uploadUrl,
data:data,
cache: false,
contentType: false,
processData: false,
success:function(rponse){
$("#"+ids).hide();
var obj = $(".dfiles").get();
$.each(obj,function(k,fle){
if($(fle).attr("rel") == rponse){
$(fle).slideUp("normal", function(){ $(this).remove(); });
}
});
if (f+1 < file.length) {
self._uploader(file,f+1);
}
}
});
} else
console.log("Invalid file format - "+file[f].name);
}
multiUploader.prototype._startUpload = function(){
if(this.all.length > 0){
for(var k=0; k<this.all.length; k++){
var file = this.all[k];
this._uploader(file,0);
}
}
}
String.prototype._unique = function(){
return this.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
}
this._init();
}
function initMultiUploader(){
new multiUploader(config);
}
Try to modify multiUploader.prototype._uploader = function(file,f)
and add a line after data.append('index',ids); with something like:
data.append('item_id','12345'); <-- you can extract the item_id by a url param, div id....
Then in your upload.php you will catch the item_id POST data