Is there any way for a client to upload a file in an HTML form (e.g. .txt or .csv formats) to a JavaScript variable as a string using only JavaScript? If so, could you provide a simple example? I don't want to use any PHP.
-
2Have a look at the FileReader APIyent– yent2013-01-04 10:27:51 +00:00Commented Jan 4, 2013 at 10:27
-
Is this the only way to do it?zdebruine– zdebruine2013-01-04 10:28:25 +00:00Commented Jan 4, 2013 at 10:28
-
ahh i noticed no php! well, with only JS it is not possible! because it is client side scripting not server side ;)Talha Akbar– Talha Akbar2013-01-04 10:31:04 +00:00Commented Jan 4, 2013 at 10:31
-
1It is possible, once again with the FileReader API, it is a javascript only api !yent– yent2013-01-04 10:31:39 +00:00Commented Jan 4, 2013 at 10:31
-
1@wagtail It has nothing to do with Jquery it is an issue which Javascript version do you want to use. The last one supports this api. Javascript 1.5 or older doesn't support that.Reporter– Reporter2013-01-04 10:33:32 +00:00Commented Jan 4, 2013 at 10:33
|
Show 1 more comment
2 Answers
Here is a quick and dirty example based on a form named "myform" that contains a file input named "myfile" :
document.forms['myform'].elements['myfile'].onchange = function(evt) {
if(!window.FileReader) return; // Browser is not compatible
var reader = new FileReader();
reader.onload = function(evt) {
if(evt.target.readyState != 2) return;
if(evt.target.error) {
alert('Error while reading file');
return;
}
filecontent = evt.target.result;
document.forms['myform'].elements['text'].value = evt.target.result;
};
reader.readAsText(evt.target.files[0]);
};
Here's the associated HTML form:
<form id="myform">
<p>
<input id="myfile" name="files[]" multiple="" type="file" />
<textarea id="text" rows="20" cols="40">nothing loaded</textarea>
</p>
</form>
and a jsfiddle to demo it.
Comments
This variation on yent's answer manages multiple uploads and uses jquery:
HTML:
<form id="myform">
<p>
<input id="myfile" name="files[]" multiple="" type="file" />
<textarea id="text" rows="20" cols="40">nothing loaded</textarea>
</p>
</form>
script:
$("#myfile").on("change", function (changeEvent) {
for (var i = 0; i < changeEvent.target.files.length; ++i) {
(function (file) { // Wrap current file in a closure.
var loader = new FileReader();
loader.onload = function (loadEvent) {
if (loadEvent.target.readyState != 2)
return;
if (loadEvent.target.error) {
alert("Error while reading file " + file.name + ": " + loadEvent.target.error);
return;
}
console.log(loadEvent.target.result.length); // Your text is in loadEvent.target.result
};
loader.readAsText(file);
})(changeEvent.target.files[i]);
}
});
Worth noting:
- You must use one FileReader for each (concurrent) file read. Otherwise you see an exception like
The object is already busy reading. - The loadEvent callbacks will be called in an arbitrary order, likely dependent on the size of the upload.
- The loadEvent closure will see the
ivalue which ended the loop. - FileReader results are NOT arrays; they have no forEach.
This jsfiddle demo preserves upload order by laying out divs in the change handler.