multiple file upload using html5 drag-and-drop fails as multiple files get same content - drag-and-drop

I need to transfer all the files dropped on an element to a server using HTML5 drag and drop.
I provided the corresponding js code below. I have a servlet in the server side to collect the files and put it in a folder. This is working fine if I drop 1 or 2 files on the page. But, if i drop 4-10 files, all the files are getting created in the server but multiple files are set to same content and some files content is 0K.
Can any of you please tell me how to achieve the correct behavior.
My requirement is similar to gmail attachments!!
Any solution which makes a sequential upload of files is much appreciable.
/*
* Upload files to the server using HTML 5 Drag and drop from the folders on your local computer
*/
function uploader(place, status, target, show) {
// Upload image files
upload = function(file) {
// Firefox 3.6, Chrome 6, WebKit
if(window.FileReader) {
// Once the process of reading file
this.loadEnd = function() {
bin = reader.result;
xhr = new XMLHttpRequest();
xhr.open('POST', target+'?up=true', false);
var body = bin;
xhr.setRequestHeader('content-type', 'multipart/form-data;');
xhr.setRequestHeader("file-name", file.name );
xhr.setRequestHeader("mime-type", file.type );
// Firefox 3.6 provides a feature sendAsBinary ()
if(xhr.sendAsBinary != null) {
xhr.sendAsBinary(body);
// Chrome 7 sends data but you must use the base64_decode on the PHP side
} else {
xhr.open('POST', target+'?up=true&base64=true', true);
xhr.setRequestHeader('UP-FILENAME', file.name);
xhr.setRequestHeader('UP-SIZE', file.size);
xhr.setRequestHeader('UP-TYPE', file.type);
xhr.send(window.btoa(bin));
}
if (show) {
var newFile = document.createElement('div');
newFile.innerHTML = 'Loaded : '+file.name+' size '+file.size+' B';
document.getElementById(show).appendChild(newFile);
}
if (status) {
document.getElementById(status).innerHTML = 'Loaded : 100%<br/>Next file ...';
}
};
// Loading errors
this.loadError = function(event) {
switch(event.target.error.code) {
case event.target.error.NOT_FOUND_ERR:
document.getElementById(status).innerHTML = 'File not found!';
break;
case event.target.error.NOT_READABLE_ERR:
document.getElementById(status).innerHTML = 'File not readable!';
break;
case event.target.error.ABORT_ERR:
break;
default:
document.getElementById(status).innerHTML = 'Read error.';
}
};
// Reading Progress
this.loadProgress = function(event) {
if (event.lengthComputable) {
var percentage = Math.round((event.loaded * 100) / event.total);
document.getElementById(status).innerHTML = 'Loaded : '+percentage+'%';
}
};
// Preview images
this.previewNow = function(event) {
bin = preview.result;
var img = document.createElement("img");
img.className = 'addedIMG';
img.file = file;
img.src = bin;
document.getElementById(show).appendChild(img);
};
reader = new FileReader();
// Firefox 3.6, WebKit
if(reader.addEventListener) {
reader.addEventListener('loadend', this.loadEnd, false);
if (status != null)
{
reader.addEventListener('error', this.loadError, false);
reader.addEventListener('progress', this.loadProgress, false);
}
// Chrome 7
} else {
reader.onloadend = this.loadEnd;
if (status != null)
{
reader.onerror = this.loadError;
reader.onprogress = this.loadProgress;
}
}
var preview = new FileReader();
// Firefox 3.6, WebKit
if(preview.addEventListener) {
preview.addEventListener('loadend', this.previewNow, false);
// Chrome 7
} else {
preview.onloadend = this.previewNow;
}
// The function that starts reading the file as a binary string
reader.readAsBinaryString(file);
// Preview uploaded files
if (show) {
preview.readAsDataURL(file);
}
// Safari 5 does not support FileReader
} else {
xhr = new XMLHttpRequest();
xhr.open('POST', target+'?up=true', true);
xhr.setRequestHeader('UP-FILENAME', file.name);
xhr.setRequestHeader('UP-SIZE', file.size);
xhr.setRequestHeader('UP-TYPE', file.type);
xhr.send(file);
if (status) {
document.getElementById(status).innerHTML = 'Loaded : 100%';
}
if (show) {
var newFile = document.createElement('div');
newFile.innerHTML = 'Loaded : '+file.name+' size '+file.size+' B';
document.getElementById(show).appendChild(newFile);
}
}
};
// Function drop file
this.drop = function(event) {
event.preventDefault();
var dt = event.dataTransfer;
var files = dt.files;
for (var i = 0; i<files.length; i++) {
var file = files[i];
upload(file);
}
};
// The inclusion of the event listeners (DragOver and drop)
this.uploadPlace = document.getElementById(place);
this.uploadPlace.addEventListener("dragover", function(event) {
event.stopPropagation();
event.preventDefault();
}, true);
this.uploadPlace.addEventListener("drop", this.drop, false);
}
Thank you.

I spent sometimes this morning in analyzing the same code from html5uploader. With some lucks, I found the root cause.
Change reader = new FileReader(); to var reader = new FileReader(); should solve the issue.
I bet this is because javascripts behaviour of auto-declaring undeclared variable as global variable. This caused the reader variable being reused by all the uploade(file) calls when more than one file is dropped to the browser.
Cheers!

Related

angular4 upload image and pass to server and save into database(express and mongoose, mongodb)

Is there anyone knows how to upload an image within Angular 4 environment, then sending this data to the backend as express server, and using mongoose to store into mongodb? if anyone knows, please post the answer. Thank
File input
{{imgfile.errors | json}}
<div class="alert alert-danger"
*ngIf="size >= 300000">
<strong>
Can't upload this image. check image size!!!
</strong>
</div>
Script
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length > 0) {
console.log(event.target.files)
let file = event.target.files[0];enter code here
this.size = file.size;
console.log(file.size);
if (file.size <= 300000) {
this.picSize = true;
}
reader.onload = () => {
this.new_food.image = reader.result;
};
reader.readAsDataURL(file);
}
}
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length > 0) {
console.log(event.target.files)
let file = event.target.files[0];enter code here
this.size = file.size;
console.log(file.size);
if (file.size <= 300000) {
this.picSize = true;
}
reader.onload = () => {
this.new_food.image = reader.result;
};
reader.readAsDataURL(file);
}
}

Asynchronous function in SAPUI5

I'm using a function to open a dialog in SAPUI5. While this dialog is opening, some data should be set in the local storage of the browser. However, when I add the local storage function, it takes a few seconds to open the dialog.
Is there a way I can make the local storage async? I tried putting the function of the local storage after the opening of the dialog. But it doesn't change anything..
/* WHEN THE USER CLICKS ON AN ASSIGNMENT IN THE CALENDAR */
onClickAssignment: function(oEvent) {
var oAppointment = oEvent.getParameter("appointment");
this.lastAppointment = oAppointment;
if (oAppointment) {
var key = this.byId("PC1").getViewKey();
if (key === "Month") {
if (!this._oDetailsDialog || this._oDetailsDialog === null) {
// show assignment dialog
this._oDetailsDialog = sap.ui.xmlfragment(this.fragmentDetailsId, "be.xxxxxxxxxxx.fragment.viewAssignment", this);
this.getView().addDependent(this._oDetailsDialog);
}
} else {
if (!this._oDetailsDialog || this._oDetailsDialog === null) {
// show subassignment dialog
this._oDetailsDialog = sap.ui.xmlfragment(this.fragmentDetailsId, "be.xxxxxxxxxxx.fragment.viewSubassignment", this);
this.getView().addDependent(this._oDetailsDialog);
}
}
this.oAppBC = oAppointment.getBindingContext();
this._oDetailsDialog.setBindingContext(this.oAppBC);
this._oDetailsDialog.open();
this.lastClickedAssignment = oAppointment.getProperty("assignment");
this.lastClickedSubassignment = oAppointment.getProperty("subassignment");
//SET LOCAL STORAGE
// var stringifiedContext = CircularJSON.stringify(oAppointment.getBindingContext());
// var stringifiedAssignment = CircularJSON.stringify(oAppointment.getProperty("assignment"));
// var stringifiedSubassignment = CircularJSON.stringify(oAppointment.getProperty("subassignment"));
// this.setLocalStorage("context", stringifiedContext);
// this.setLocalStorage("assignment", stringifiedAssignment);
// this.setLocalStorage("subassignment", stringifiedSubassignment);
}
},
You can detach execution of that part of the code from the main execution thread by wrapping it into setTimeout:
/* WHEN THE USER CLICKS ON AN ASSIGNMENT IN THE CALENDAR */
onClickAssignment: function(oEvent) {
var oAppointment = oEvent.getParameter("appointment");
this.lastAppointment = oAppointment;
if (oAppointment) {
var key = this.byId("PC1").getViewKey();
if (key === "Month") {
if (!this._oDetailsDialog || this._oDetailsDialog === null) {
// show assignment dialog
this._oDetailsDialog = sap.ui.xmlfragment(this.fragmentDetailsId, "be.xxxxxxxxxxx.fragment.viewAssignment", this);
this.getView().addDependent(this._oDetailsDialog);
}
} else {
if (!this._oDetailsDialog || this._oDetailsDialog === null) {
// show subassignment dialog
this._oDetailsDialog = sap.ui.xmlfragment(this.fragmentDetailsId, "be.xxxxxxxxxxx.fragment.viewSubassignment", this);
this.getView().addDependent(this._oDetailsDialog);
}
}
this.oAppBC = oAppointment.getBindingContext();
this._oDetailsDialog.setBindingContext(this.oAppBC);
this._oDetailsDialog.open();
this.lastClickedAssignment = oAppointment.getProperty("assignment");
this.lastClickedSubassignment = oAppointment.getProperty("subassignment");
setTimeout(function () {
//SET LOCAL STORAGE
var stringifiedContext = CircularJSON.stringify(oAppointment.getBindingContext());
var stringifiedAssignment = CircularJSON.stringify(oAppointment.getProperty("assignment"));
var stringifiedSubassignment = CircularJSON.stringify(oAppointment.getProperty("subassignment"));
this.setLocalStorage("context", stringifiedContext);
this.setLocalStorage("assignment", stringifiedAssignment);
this.setLocalStorage("subassignment", stringifiedSubassignment);
});
}
},
OR you can also do it after open:
this._oDetailsDialog.attachEventOnce('afterOpen', function () {
//SET LOCAL STORAGE
// ...
});

Is there a way to use fs sync functions with browserify?

I already tried the brfs transformation, but I got the following error message:
08 03 2016 16:50:14.894:ERROR [framework.browserify]: bundle error
08 03 2016 16:50:14.894:ERROR [framework.browserify]: Error: tried to statically call { readFile: [Function: readFile], readFileSync: [Function: readFileSync], readdir: [Function: readdir], readdirSync: [Function: readdirSync] } as a function while parsing file
...
PhantomJS 1.9.8 (Windows 7 0.0.0) ERROR
You need to include some adapter that implements __karma__.start method!
when I try to use var fs = require("fs"); console.log(fs.readFileSync) in my code. Is there a way to use sync fs functions with browserify?
I want to process some non-js files which are served but no included by karma and not preprocessed by browserify. So what I need is glob and read. Any other idea how to process these files? The ideal solution would be to do it with nodejs, but I am not sure how to send the data from nodejs to the browser by using karma.
I did not manage to make the brfs work. I created a simple fs shim instead, which supports the following features:
existsSync(path) -> true/false
readdirSync(path) -> basename[]
statSync(path) -> {isDirectory}
readFileSync(path,"utf8") -> string
It uses path-browserify, so you need to replace the require("path") dependency if you use it in a non-browserify environment. Be aware that this fs shim uses window.__karma__.files, to build a directory and file tree, so it won't work without Karma. You can use the same logic if you are able to collect the file paths from browserify. I guess you need to write a browserify plugin for that.
module.exports = (function () {
var path = require("path");
function absolutePath(relativePath) {
return path.resolve(path.normalize(relativePath.split("\\").join("/")));
}
var KarmaFileSystem = function () {
this.registry = new KarmaPathRegistry();
this.converter = new KarmaUriPathConverter("/base/", "/");
this.reader = new KarmaFileReader(this.converter);
var servedUris = Object.keys(window.__karma__.files);
var servedFiles = this.converter.parseUris(servedUris);
servedFiles.forEach(this.registry.addFile, this.registry);
};
KarmaFileSystem.prototype = {
constructor: KarmaFileSystem,
workingDirectory: "/",
existsSync: function (path) {
return this.registry.exists(path);
},
readdirSync: function (path) {
return this.registry.getContent(path);
},
statSync: function (path) {
return {
isDirectory: function () {
return this.registry.isDirectory(path);
}.bind(this)
};
},
readFileSync: function (file, encoding) {
if (encoding !== "utf8")
throw new Error("This fs.readFileSync() shim does not support other than utf8 encoding.");
if (!this.registry.isFile(file))
throw new Error("File does not exist: " + file);
return this.reader.readFile(file);
}
};
var KarmaPathRegistry = function KarmaPathRegistry() {
this.paths = {};
};
KarmaPathRegistry.prototype = {
constructor: KarmaPathRegistry,
addFile: function (file) {
file = absolutePath(file);
this.paths[file] = KarmaPathRegistry.TYPE_FILE;
var parentDirectory = path.dirname(file);
this.addDirectory(parentDirectory);
},
addDirectory: function (directory) {
directory = absolutePath(directory);
this.paths[directory] = KarmaPathRegistry.TYPE_DIRECTORY;
var parentDirectory = path.dirname(directory);
if (parentDirectory != directory)
this.addDirectory(parentDirectory);
},
isFile: function (file) {
file = absolutePath(file);
return this.exists(file) && this.paths[file] === KarmaPathRegistry.TYPE_FILE;
},
isDirectory: function (directory) {
directory = absolutePath(directory);
return this.exists(directory) && this.paths[directory] === KarmaPathRegistry.TYPE_DIRECTORY;
},
exists: function (node) {
node = absolutePath(node);
return this.paths.hasOwnProperty(node);
},
getContent: function (directory) {
if (!this.isDirectory(directory))
throw new Error("Not a directory: " + directory);
directory = absolutePath(directory);
return Object.keys(this.paths).filter(function (node) {
if (node === directory)
return false;
var parentDirectory = path.dirname(node);
return parentDirectory === directory;
}, this).map(function (node) {
return path.basename(node);
});
}
};
KarmaPathRegistry.TYPE_FILE = 0;
KarmaPathRegistry.TYPE_DIRECTORY = 1;
var KarmaUriPathConverter = function KarmaUriPathConverter(baseUri, workingDirectory) {
this.workingDirectory = workingDirectory;
this.workingDirectoryPattern = this.patternFromBase(workingDirectory);
this.baseUri = baseUri;
this.baseUriPattern = this.patternFromBase(baseUri);
};
KarmaUriPathConverter.prototype = {
constructor: KarmaUriPathConverter,
patternFromBase: function (string, flags) {
var pattern = "^" + string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return new RegExp(pattern, flags);
},
parseUris: function (uris) {
return uris.filter(function (uri) {
return this.baseUriPattern.test(uri)
}, this).map(function (uri) {
return uri.replace(this.baseUriPattern, this.workingDirectory);
}, this);
},
buildUri: function (file) {
file = absolutePath(file);
if (!this.workingDirectoryPattern.test(file))
throw new Error("Path is not in working directory: " + file);
return file.replace(this.workingDirectoryPattern, this.baseUri);
}
};
var KarmaFileReader = function KarmaFileReader(converter) {
this.converter = converter;
};
KarmaFileReader.prototype = {
constructor: KarmaFileReader,
readFile: function (file) {
var uri = this.converter.buildUri(file);
var xhr = new XMLHttpRequest();
xhr.open("get", uri, false);
xhr.send();
return xhr.responseText;
}
};
return new KarmaFileSystem();
})();

phonegap choose audio file and upload it on server

I am developing app with phonegap and jQuery mobile.
I want to select audio file from playlist then upload it on server.
I have google it but there no link that shows to select audio file then upload it on server,
I don't want to record any audio.
I just want to upload audio(that is in my music folder or play list) on server.
Please help me.
function uploadVoice(fileName, dirName, fileMime, uploadURL) {
var win = function (r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
};
var fail = function(error) {
alert("An error has occurred: Code = " = error.code);
};
// file system fail
var fsFail = function(error) {
alert("failed with error code: " + error.code);
};
var dirFail = function(error) {
alert("Directory error code: " + error.code);
};
var fileURI;
var gotFileSystem = function (fileSystem) {
fileSystem.root.getDirectory(dirName, {
create: false
}, function (dataDir) {
fileURI = dataDir.fullPath;
fileURI = fileURI + '/' + fileName;
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = fileMime;
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURI, uploadURL, win, fail, options);
}, dirFail);
};
// get file system to copy or move image file to
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem, fsFail);
}
Got this from the link Phonegap - How can I upload an audio file after recording with Phonegap's media.startRecord

How to handle a drag-event within Google Earth plugin?

My javascript is very weak.
Is it possible to modify the same code below to do the following:
Make the objects loaded draggable
When the object is dropped, an ajax request to something like:
http://.../moveTo?lat=new_lat&long=new_long&id=some_way_to_uniquely_id_the_object
Any advice to offer?
Sample Code:
var ge;
// store the object loaded for the given file... initially none of the objects
// are loaded, so initialize these to null
var currentKmlObjects = {
'red': null,
'yellow': null,
'green': null
};
google.load("earth", "1");
function init() {
// Create checkboxes
var content = document.getElementById('content');
var inputHTML = 'Placemarks:<br/>';
inputHTML += '<input type="checkbox" id="kml-red-check" onclick="toggleKml(\'red\');"/>' +
'<label for="kml-red-check">Red</label>' +
'<input type="checkbox" id="kml-yellow-check" onclick="toggleKml(\'yellow\');"/>' +
'<label for="kml-yellow-check">Yellow</label>' +
'<input type="checkbox" id="kml-green-check" onclick="toggleKml(\'green\');"/>' +
'<label for="kml-green-check">Green</label>';
content.innerHTML = inputHTML;
google.earth.createInstance('content', initCB, failureCB);
}
function initCB(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
// add a navigation control
ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
// add some layers
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);
// fly to Santa Cruz
var la = ge.createLookAt('');
la.set(37, -122,
0, // altitude
ge.ALTITUDE_RELATIVE_TO_GROUND,
0, // heading
0, // straight-down tilt
5000 // range (inverse of zoom)
);
ge.getView().setAbstractView(la);
// if the page loaded with checkboxes checked, load the appropriate
// KML files
if (document.getElementById('kml-red-check').checked)
loadKml('red');
if (document.getElementById('kml-yellow-check').checked)
loadKml('yellow');
if (document.getElementById('kml-green-check').checked)
loadKml('green');
document.getElementById('installed-plugin-version').innerHTML =
ge.getPluginVersion().toString();
}
function failureCB(errorCode) {
}
function toggleKml(file) {
// remove the old KML object if it exists
if (currentKmlObjects[file]) {
ge.getFeatures().removeChild(currentKmlObjects[file]);
currentKmlObject = null;
}
// if the checkbox is checked, fetch the KML and show it on Earth
var kmlCheckbox = document.getElementById('kml-' + file + '-check');
if (kmlCheckbox.checked)
loadKml(file);
}
function loadKml(file) {
var kmlUrl = 'http://earth-api-samples.googlecode.com/svn/trunk/' +
'examples/static/' + file + '.kml';
// fetch the KML
google.earth.fetchKml(ge, kmlUrl, function(kmlObject) {
// NOTE: we still have access to the 'file' variable (via JS closures)
if (kmlObject) {
// show it on Earth
currentKmlObjects[file] = kmlObject;
ge.getFeatures().appendChild(kmlObject);
} else {
// bad KML
currentKmlObjects[file] = null;
alert('Bad KML');
// uncheck the box
document.getElementById('kml-' + file + '-check').checked = '';
}
});
}
google.setOnLoadCallback(init);
For bonus points, can I get the kml to be reloaded afterwards?
To make the objects draggable you need to set up some event listeners and handle the movement in the callback function. I presume the objects you wish to drag are place-marks (KmlPlacemark) if so you need something like this...(NB: This is untested and written here so there could be some typos.)
var dragging = false; // the object being dragged
var url = "http://.../moveTo?"; // path to your cgi script
function init() {
// Rest of your method body...
google.earth.addEventListener(ge.getGlobe(), "mousedown", function(e)
{
// if it is a place mark
if(e.getTarget().getType() == 'KmlPlacemark')
{
// set it as the dragging target
dragging = e.getTarget();
}
});
google.earth.addEventListener(ge.getGlobe(), "mouseup", function(e)
{
// drop on mouse up (if we have a target)
if(dragging) {
// build the query string
// ...you could use getName or getSnippet rather than getId
var query = "lat=" + dragging.getGeometry().getLatitude() +
"&long=" + dragging.getGeometry().getLongitude() +
"&id=" + dragging.getId();
// send the query to the url
httpPost(url, query);
// clear the dragging target
dragging = false;
}
});
google.earth.addEventListener(ge.getGlobe(), "mousemove", function(e)
{
// when the mouse moves (if we have a dragging target)
if(dragging) {
// stop any balloon opening
e.preventDefault();
// drag the object
// i.e. set the placemark location to cursor the location
dragging.getGeometry().setLatLng(e.getLatitude(), e.getLongitude());
}
});
}
// send a HTTP POST request
// could use jQuery, etc....
function httpPost(url, query) {
var httpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.httpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.httpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.httpReq .open('POST', url, true);
self.httpReq .setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.httpReq .onreadystatechange = function() {
if (self.httpReq .readyState == 4) {
// do something...
alert(self.httpReq.responseText);
}
}
self.httpReq.send(query);
}