I need a way to get all the images from a local folder for a presentation that will also run locally. There will be no attempt for a server to take the images from a local folder since that is not possible/the case.
I need to use .js since I can't use .php (which would be easier) since it runs on a local PC.
Say I need to take all the images from learn/
I have tried various solutions that can be found here, here and here but none worked.
I think your best option is to use the new File API in Javascript. Is has a lot of functions to read files from the file system.
<input type="file" id="fileinput" multiple />
<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( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>
(code from here)
You can find a good explanation and helpful code here.
Thanks to Patrick Hofman's answer, I modified the code and ended up with this :
$(document).ready(function(){
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;
$('body').append('<h1>' + f.name + '</h1><img src="learn/' + f.name + '"/>');
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
});
Related
I am Java developer by birth with very limited hands on client side programming, so need help here.
I am basically looking for a way to create single page HTML/JavaScript application to read my local file system. I want to list directories and files within specific directory on my HTML page. What are the ways to achieve this.
Please note that I want to avoid server side coding or web application and stuff. Just need plain HTML and/or Javascript or any Javascript framework to do this for me. And I need it to be working primarily on chrome.
Please suggest.
Though its not a good to read the files at client side lot of security and access issues may occur. Still if you want you Can read the file at client side using filereader,check the following example:
<input type="file" id="fileinput" multiple />
<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;
console.log(contents);
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>
Im wondering if is possible to do a function through javascript where I will write a function to write the contents of an external JS file into an html file.
its like this:
function insertInlineScript (path){
var readScriptFromPath (path){
return "<script>" + scriptContents + "</script>";
}
}
then ill just insert this to my page
insertInlineScript("/path/to/file");
insertInlineScript("/path/to/file_2");
the output of the page will be
<script>
//contents of first file
</script>
<script>
//contents of 2nd file
</script>
You can use HTML5's new File API to read your file content. Here is an example using a file input, you can reuse the code and adapt it for yourself :
<input type="file" id="fileinput" />
<script type="text/javascript">
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"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
</script>
More information here and here.
How do you get a path from a file object which is returned from an html5 input field?
Basically the phonegap app is setup to go online and download a sound file from a thirdparty website, then browse to the downloaded file and move it to the local directory. (short < 1 sec sound files).
The problem is that file objects attribute .fullPath is undefined. and getFile takes a path input, not an [object File] input.
From the following code:
<input style="opacity:0;" type="file" name="soundInput" id="soundInput"/>
<script type="text/javascript" charset="utf-8">
var soundInput = document.getElementById('soundInput');
soundInput.addEventListener('change', function(){handleFileSelect(type);}, false);
soundInput.click();
function handleFileSelect() {
var file = this.files[0]; // FileList object
var type = isThumpy;
alert("file = " + file.name + "\n full path = " + file.fullPath);
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
gotFS(fs,file,type);
}, fail);
}
function fail(error) {
alert("error " + error.code);
}
function gotFS(fileSystem, file, type) {
alert("got filesystem");
var flags = {create: false, exclusive: false};
fileSystem.root.getFile(file, flags, function(fe){
gotFileEntry(type,fe);
},fail);
}
function gotFileEntry(type, fileEntry) {
alert("got fileEntry");
fileEntry.copyTo(path, function(fe){successfulCopy(type, fe);}, fail);
}
function successfulCopy(type, fileEntry) {
alert("copy success");
setSoundByUri(type, fileEntry.name)
}
</script>
It doesn't get past "got filesystem", and it doesn't throw an error ("error " + error.code). Please help.
You can not get the path data from a file input. File inputs are read only. Try changing the approach. Use the phoneGap fileEntry to create the new file and write data from the file input to it.
like this:
<script type="text/javascript" charset="utf-8">
function handleFileSelect(type) {
var file = this.files[0]; // FileList object
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
gotFS(fs,file,type);
}, fail);
}
function gotFS(fileSystem, file, type) {
var flags = {create: true, exclusive: false};
fileSystem.root.getFile(file.name, flags, function(fe) {gotFileEntry(fe, file, type);}, fail);
}
function gotFileEntry(fileEntry, file, type) {
fileEntry.createWriter(function(w){gotFileWriter(w, file, type);}, fail);
}
function gotFileWriter(fileWriter, file, type) {
fileWriter.onwriteend = function(evt){setSoundByUri(type, path + file.name);};
var reader = new FileReader();
reader.onload = function(event) {
var rawData = event.target.result;
fileWriter.write(rawData);
};
reader.onerror = function(event){
alert("error, file could not be read" + event.target.error.code);
};
reader.readAsArrayBuffer(file);
}
function fail(error) {
alert("error " + error.code);
if (error.code == FileError.PATH_EXISTS_ERR){
alert("The file already exists.");
}
}
</script>
How can I check if the uploaded file is ascii plain text?
$("#my_file").change(function(){
//alert if not ascii
});
<input type="file" name="my_file" id="my_file" />
Using the HTML5 file APIs (which are not yet finalized and not supported by all versions of all major browsers) you could read the raw file contents via FileReader.readAsBinaryString(file) and ensure that each byte (character) has a value in the ASCII character range (0-127).
For example (see working jsFiddle here):
function ensureAsciiFile(evt) {
var file, files=evt.target.files;
for (var i=0; file=files[i]; i++) {
var reader = new FileReader();
reader.onload = (function(theFile, theReader) {
return function(e) {
var fileContents = theReader.result;
if (fileContents.match(/[^\u0000-\u007f]/)) {
alert('ERROR: non-ASCII file "' + theFile.name + '"');
} else {
alert('OK: ASCII file "' + theFile.name + '"');
}
};
})(file, reader);
reader.readAsBinaryString(file);
}
}
$('#my_file').change(ensureAsciiFile);
I am attempting to use XMLHttpRequest to upload files to the server. Here are the steps I would like the code to do:
List the file in a file list ul
Upload the file(s) while displaying a progress bar
When the file is completely uploaded, change the list item for that file to a link without the progress bar. This is where I am having a problem.
Here is the HTML code I am working with:
<h1>Upload Files</h1>
<input type='file' name='doc_upload_field[][]' multiple='multiple' id='doc_upload_field' />
<ul id='filelist'></ul>
Here is the javascript code I am working with:
function transferFailed(evt) {
alert("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
alert("The transfer has been canceled by the user.");
}
var filelist = $('#filelist');//define where the list of files will go
var url = "/";
function handleFileSelect_inputfield(evt) {
var files = evt.target.files; // FileList object
// run through each file individually.
for (var i = 0, f; f = files[i]; i++) {
var li = $("<li><strong>" + f.name + "</strong> (" + f.type +") - " + f.size + " bytes <div class='progress_bar'><div class='percent'> </div></div></li>");
filelist.append(li);//put the file in the filelist
var formData = new FormData();
formData.append(f.name, f);
//upload through xmlhttprequest
var xhr = new XMLHttpRequest();
xhr.upload.li = li;
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentLoaded = Math.round((e.loaded / e.total) * 100);
// Increase the progress bar length.
if (percentLoaded < 100) {
this.li.find(".progress_bar").addClass('loading');
this.li.find(".percent").width(percentLoaded + '%');
}
}
}, false);
xhr.upload.addEventListener("load", function(e) {
//uploading is complete
}, false);
xhr.upload.addEventListener("error", transferFailed, false);
xhr.upload.addEventListener("abort", transferCanceled, false);
xhr.open('POST', url, true);
xhr.responseType = 'text';
xhr.onload = function(e) {
if (this.readyState==4){
if (this.status == 200) {
//console.log(this.response);
console.log("finished=" + li);//returns as an object
//console.log("filename=" + f.name);//error: cannot read property 'name' of undefined
//change the list item. Not working...
this.li.find("li").html("<a href='#'>" + f.name + "</a>");
}
}
};
xhr.send(formData); // multipart/form-data
}
}
document.getElementById('doc_upload_field').addEventListener('change', handleFileSelect_inputfield, false);
Everything seems to be working, but when I want to change the list item, li, it is not recognizing it. I am able to change the progress bar length by calling:
this.li.find(".progress_bar").addClass('loading');
this.li.find(".percent").width(percentLoaded + '%');
But when I want to change the list item:
this.li.find("li").html("<a href='#'>" + f.name + "</a>");
It does not work.
Does anyone know why it would find it when changing the progress bar, but not find it after it is uploaded?
The expression
this.li.find("li")
looks for an <li> element inside the other <li> element. There isn't one, so nothing happens.
I think that just
this.li.html("<a href='#'>" + f.name + "</a>");
should be what you want. Or you could just do this:
this.li = $("<li><a href='#'>" + f.name + "</a></li>");
edit oops no that won't work because you've stuck it in the DOM already. But the first one should work.
edit — you've also got a closure-related problem (or scope-related; whatever). What you can do is something like what you've already done for the "li" value. Add another property for it to "xhr.upload":
xhr.upload.updated_li = "<a href='#'>" + f.name + "</a>";
Do that right where you set "xhr.updated.li". Then, in the event handler, you can do:
this.li.html(this.updated_li);