Javascript base64 convertion - javascript

my aswer i believe is easy. I need create a code to get base64 content in FileReader function to send to database. I try to put the base64 string and put in form type hidden but i cant do. I upload the source code bellow:
JSFIDDLE
<script type="text/javascript">
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
alert(
"name: " + f.name + "n"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
document.write(f.name);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>

Try using the function from MDN which should also support unicode:
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
alert(
"name: " + f.name + "n"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
document.getElementById('b64').innerHTML = b64EncodeUnicode(contents);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change',
readMultipleFiles, false);
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
Notes:
I tested the above using an ascii file and https://www.base64encode.org/
Removed the document.write. Instead the result is displayed in a span with id="b64" (document.getElementById('b64').innerHTML = ...)
As is, will work only for 1 file. Requires minor editing or putting back the document.write to support multiple files
Fiddle: https://jsfiddle.net/g6g1a51p/4/

Related

Why does my redirect is not working?

my script calls my redirect function to early, so the last file of a batch upload is failing. I have been search the whole morning an tried different approaches, but without success.
function uploadFile(something, callback) {
var fileInput = $('#fileList1');
//var reader = new FileReader();
console.log(fileInput);
if ( trim( fileInput.val() ).length == 0 ) {
return;
}
var fileList = [];
count = fileInput[0].files.length;
for(i = 0; i < count; i++){
loadFile(fileInput[0].files[i]);
}
function loadFile(file){
var reader = new FileReader();
var fileName = getFileNameWithExtension( file);
var file = file;
while(reader.onprogress){
console.log("reading");
}
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
if (!--count){
redirect();
}
}
reader.onerror = function(event) {
console.error("File could not be read! Code " + reader.error.message);
}
reader.readAsDataURL(file);
}
}
function redirect(){
window.location.href = '/{!tempID}';
return false;
}
Can someone give me a hint?
#
Hello, i have rewritten my methods a bit based on your suggestions. But the redirect is still called to early,...before all uploads are done.
function uploadFile() {
var fileInput = $('#fileList1');
console.log(fileInput);
if ( trim( fileInput.val() ).length == 0 ) {
return;
}
var countTwo = 0;
count = fileInput[0].files.length;
for(var i = 0; i < count; i++){
loadFile(fileInput[0].files[i], function(val){
console.log(val);
if(val === 3){
setTimeout(()=>{redirect();}, 5000);
}
});
}
function loadFile(file, callback){
var reader = new FileReader();
var fileName = getFileNameWithExtension( file);
var file = file;
while(reader.onprogress){
console.log("reading");
}
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
console.log(" ct " + countTwo + " c " + count-1);
countTwo++;
if(!--count) callback(countTwo);
}
reader.onerror = function(event) {
console.error("File could not be read! Code " + reader.error.message);
}
reader.readAsDataURL(file);
}
}
Method 1: (Recommended)
Detect when your uploading ends. And in that callback, call redirect.
Method 2:
// define your TIMEOUT first
setTimeout(()=>{redirect();}, TIMEOUT);
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
if (!--count){
setTimeout(()=>{redirect();}, 0);
}
}

How do I use FileReader.onload multiple times on a page?

I have a page that has multiple inputs for single file upload. Kind of like this:
<div id="fileUpload1">
<input id="inputField1" type="file"></input>
</div>
<div id="fileUpload2">
<input id="inputField2" type="file"></input>
</div>
<div id="fileUpload3">
<input id="inputField3" type="file"></input>
</div>
<button type="button" onclick="uploadFiles()">Upload</button>
Inside uploadFiles(), I first create an array of each file in the input fields:
var files = [];
for (var i = 1; i <= 3; i++) {
var element = document.getElementById("inputField" + i);
var file = element.files[0];
files.push(file);
}
Then I attempt to call FileReader's onLoad event for each file in the "files" array:
for (var i = 0, f; f= files[i]; i++) {
var fileName = f.name;
console.log("out: " + fileName);
var reader = new FileReader();
reader.onload = function (e) {
console.log("in: " + fileName);
addItem(e.target.result, fileName);
}
reader.readAsArrayBuffer(f);
}
addItem() is a function that works.
When I run this, only the last item in the "files" array is uploaded.
If inputField1 has a file named file1.jpg, inputField2 has a file named file2.jpg, etc, I would get the following in the console:
out: file1.jpg
out: file2.jpg
out: file3.jpg
in: file3.jpg
in: file3.jpg
in: file3.jpg
I feel like I am missing something truly fundamental with how to use FileReader. Any help would be appreciated. Thank you!
<button type="button" onclick="uploadFiles(readF)">Upload</button>
function uploadFiles(){
var files = [];
for (var i = 1; i <= 3; i++) {
var element = document.getElementById("inputField" + i);
var file = element.files[0];
files.push(file);
}
for (var i = 0, f; f= files[i]; i++) {
console.log("out: " + fileName);
readF(f);
}
}
function readF(f){
var reader = new FileReader();
reader.onload = function (e) {
var fileName = f.name;
console.log("in: " + fileName);
addItem(e.target.result, fileName);
}
reader.readAsArrayBuffer(f);
}
It looks like the problem was with the "var fileName = f.name;" being outside the onload. I think the e.target.result would have been correct in the original example. The output would also be dependent on execution order of things. If the browser called each onload directly after readAsArrayBuffer, the out: would like right, but it looks like your case, it was running the loop all 3 times and then calling all the onloads.
So it looks like the simplest fix to original code would have been to change:
for (var i = 0, f; f= files[i]; i++) {
var fileName = f.name;
console.log("out: " + fileName);
var reader = new FileReader();
reader.onload = function (e) {
console.log("in: " + fileName);
addItem(e.target.result, fileName);
}
reader.readAsArrayBuffer(f);
}
TO
for (var i = 0, f; f= files[i]; i++) {
console.log("out: " + fileName);
var reader = new FileReader();
reader.onload = function (e) {
var fileName = f.name;
console.log("in: " + fileName);
addItem(e.target.result, fileName);
}
reader.readAsArrayBuffer(f);
}
Or if possible reference the file name from "e.target".

convert HTML file contents into a string in Javascript

I'm asking users to upload and HTML file, I would like to convert the contents of the HTML file into a string.
HTML file:
<form action="">
<input type="file" name="pic" accept="html" id = "htmlFile">
</form>
JAVASCRIPT
function readTextFile(file) //this is all wrong I think
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
alert(allText);
}
}
}
rawFile.send(null);
}
If I understand you correctly, you can read the file after the input change with FileReader like this:
function readSingleFile(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "contents:" + contents
);
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
document.getElementById('htmlFile').addEventListener('change', readSingleFile, false);
<form action="">
<input type="file" name="pic" accept="html" id="htmlFile">
</form>
Source

Cloning a File object to a web Worker

I am experimenting with web Workers to improve file upload performance. I am working on an example from this post about large file uploads. I have a (somewhat) more complete code sample that works in Chrome (36.0.1985.143) and Safari (7.0.3 (9537.75.14)) but not in Firefox (31.0). I don't have server code to share, but the client side code is enough to see whether the browser is pushing the slices. According to MDN, File and FileList are both clonable objects, so is this a bug in Firefox?
The original link came via this post on StackOverflow.
In Firefox, I hit an error:
(DataCloneError: The object could not be cloned.)
on this line:
worker.postMessage({
'files' : files
});
Code follows:
index.html
<html>
<head>
<script>
var worker = new Worker('fileupload.js');
worker.onmessage = function(e) {
alert(e.data);
}
worker.onerror = werror;
function werror(e) {
console.log('ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message);
}
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files;
if(evt.dataTransfer === undefined ){
files = document.getElementById('files').files;
}else{
files = evt.dataTransfer.files||evt.target.files;
}
// FileList object.
worker.postMessage({
'files' : files
});
//Sending File list to worker
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
// Explicitly show this is a copy.
}
function setcode(){
// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
document.getElementById('files').addEventListener('change', handleFileSelect, false);
}
</script>
</head>
<body >
<input type="file" id="files" name="files" multiple />
<div id="drop_zone" style="width:500px;height:50%;">
Drop files here
</div>
<div>
<input type>
</div>
<output id="list"></output>
<script>
setcode();
</script>
</body>
</html>
fileupload.js
var file = [], p = true;
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', false);
xhr.onload = function(e) {
};
xhr.send(blobOrFile);
}
function process() {
for (var j = 0; j <file.length; j++) {
var blob = file[j];
const BYTES_PER_CHUNK = 1024 * 1024;
// 1MB chunk sizes.
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while (start < SIZE) {
if ('mozSlice' in blob) {
var chunk = blob.mozSlice(start, end);
} else if ('webkitSlice' in blob) {
var chunk = blob.webkitSlice(start, end);
}else{
var chunk = blob.slice(start, end);
}
upload(chunk);
start = end;
end = start + BYTES_PER_CHUNK;
}
p = ( j = file.length - 1) ? true : false;
self.postMessage(blob.name + " Uploaded Succesfully");
}
}
self.onmessage = function(e) {
for (var j = 0; j < e.data.files.length; j++)
file.push(e.data.files[j]);
if (p) {
process()
}
}

Asynchronous execution in javascript any solution to control execution?

I need a solution to control code execution in javascript.I want code on next line should not be executed unless the code on current line is completely executed.
Is there any solution?
function handleFileSelect(evt) {
var files = evt.target.files;
for (var i = 0; i < files.length; i++) {
alert("for");
f = files[i];
fileExtension = f.name.split('.').pop();
if(fileExtension != 'kml' && fileExtension !='kmz' && fileExtension != 'csv'){
alert('Unsupported file type ' + f.type + '(' + fileExtension + ')');
return;
}
var fileReaderkmlcsv = new FileReader();
fileReaderkmlcsv.onloadend = loadend;
fileReaderkmlcsv.onerror = function(event) {
alert("ERROR: " + event.target.error.code);
};
fileReaderkmlcsv.readAsText(f);
} //- end for
} //handleFileSelect
function loadend(theFile) {
alert("loadend");
//code for processing my files
}
The issue is that loadend is running as soon as any one of the FileReaders has completed loading. You'll need to redesign the code to wait for all 3 of them to finish, something like:
function handleFileSelect(evt) {
var files = evt.target.files;
var fileReaders = [];
var loadCount = 0;
for (var i = 0; i < files.length; i++) {
f = files[i];
fileExtension = f.name.split('.').pop();
if(fileExtension != 'kml' && fileExtension !='kmz' && fileExtension != 'csv'){
alert('Unsupported file type ' + f.type + '(' + fileExtension + ')');
return;
}
function fileLoaded() {
loadCount++;
//Check if we've loaded all the files
if (loadCount == files.length) {
loadend(fileReaders);
}
}
var fileReaderkmlcsv = new FileReader();
fileReaderkmlcsv.onloadend = fileLoaded;
fileReaderkmlcsv.onerror = function(event) {
alert("ERROR: " + event.target.error.code);
};
fileReaderkmlcsv.readAsText(f);
fileReaders.push(fileReaderkmlcsv);
}
}
function loadend(files) {
//files now contains an array of completed FileReader objects
}
Note that I don't have direct experience of the FileReader object itself - if onloadend doesn't fire if an error occurs, you'll need to put similar logic in the onerror event as well to make sure that the loadCount variable still gets incremented/checked etc.

Categories

Resources