reading txt file into a textarea using javascript - javascript

Here is my html and javascript code using document.ready function
html script here...
<textarea id="recipients" name="recipients" class="form-control"></textarea>
<input name="file" type="file" id="files" class="form-control" value="">
<a id="fetch_number" class="btn btn-primary btn-sm" href="">pull text file</a>
Here is the javascript code:
$(document).ready(function() {
$('#fetch_number').on('click', function() {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
if (window.File && window.FileReader && window.FileList && window.Blob) {
var text_file = document.getElementById('files');
var files = text_file.files;
var file = files[0];
var extension = file.name.split('.').pop();
var start = 0;
var stop = file.size - 1;
var reader = new FileReader();
reader.onload = function(e){
var output = e.target.result;
output = output.split("/\r\n|\n/");
var string = '';
for (var i=0; i < output.length; i++) {
var data = allTextLines[i].split(',');
string = data[1] + ',';
}
return string;
$("#recipients").text(string);
};
} else {
alert('The File APIs are not fully supported by your browser.');
}
});
});
Here is the javascript code I don't know what to do anymore if I do not browse for any text file it gives me response for the (!files.length)
, but I do not know why others don't work.

You are having problems because
You are trying to invoke code after the line return string;
You tried to return from an asynchronous function
Try something like this instead
function readTextFile(file, callback, encoding) {
var reader = new FileReader();
reader.addEventListener('load', function (e) {
callback(this.result);
});
if (encoding) reader.readAsText(file, encoding);
else reader.readAsText(file);
}
function fileChosen(input, output) {
if (input.files && input.files[0]) {
readTextFile(
input.files[0],
function (str) {
output.value = str;
}
);
}
}
$('#files').on('change', function () {
fileChosen(this, document.getElementById('recipients'));
});
<textarea id="recipients" name="recipients" class="form-control"></textarea>
<input name="file" type="file" id="files" class="form-control" value="">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

Related

Processing multiple file uploads and writing them to google sheets with JavaScript and Google Apps Script [duplicate]

<input type='file' name="image" onchange="preview(this);" multiple="multiple" />
window.preview = function (input){
if(input.files && input.files[0]) {
var reader = new FileReader();
reader.readAsDataURL(input.files[0]);
reader.onload = function(e){
$("#previewImg").append("<img src='" + e.target.result +"'>");
}
}
}
I have a function using file reader to preview image, It works fine in single file.
However I try to achieve multiple files.
My question is how to get input files array, loop files through file reader and append img
Javascript Solution Fiddle DEMO
<input id="files" type="file" multiple="multiple" />
<output id="result" />
Pure JavaScript:
function handleFileSelect(event) {
//Check File API support
if (window.File && window.FileList && window.FileReader) {
var files = event.target.files; //FileList object
var output = document.getElementById("result");
for (var i = 0; i < files.length; i++) {
var file = files[i];
//Only pics
if (!file.type.match('image')) continue;
var picReader = new FileReader();
picReader.addEventListener("load", function (event) {
var picFile = event.target;
var div = document.createElement("div");
div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" + "title='" + file.name + "'/>";
output.insertBefore(div, null);
});
//Read the image
picReader.readAsDataURL(file);
}
} else {
console.log("Your browser does not support File API");
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
jQuery Solution
jQuery File Input Image Preview Before It Is Uploaded
<form id="form1" runat="server">
<input type='file' id="inputFile" />
<img id="image_upload_preview" src="http://placehold.it/100x100" alt="your image" />
</form>
jQuery:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image_upload_preview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#inputFile").change(function () {
readURL(this);
});
Working Fiddle
Javascript
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function (theFile) {
return function (e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('previewImg').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
More details about Files API and reference help for this answer...
Using your code Working Fiddle
HTML
<input type='file' name="image" onchange="preview(this);" multiple="multiple" />
<div id='previewImg'></div>
Javascript
window.preview = function (input) {
if (input.files && input.files[0]) {
$(input.files).each(function () {
var reader = new FileReader();
reader.readAsDataURL(this);
reader.onload = function (e) {
$("#previewImg").append("<img class='thumb' src='" + e.target.result + "'>");
}
});
}
}
Muliple File previewing using Jquery and DataURL
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script language="Javascript">
$(function () {
$("#browse").change(function () {
if (typeof (FileReader) != "undefined") {
var dvPreview = $("#preview");
dvPreview.html("");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
$($(this)[0].files).each(function () {
var file = $(this);
if (regex.test(file[0].name.toLowerCase())) {
var reader = new FileReader();
reader.onload = function (e) {
var img = $("<img />");
img.attr("style", "height:100px;width: 100px");
img.attr("src", e.target.result);
dvPreview.append(img);
}
reader.readAsDataURL(file[0]);
} else {
alert(file[0].name + " is not a valid image file.");
dvPreview.html("");
return false;
}
});
} else {
alert("This browser does not support HTML5 FileReader.");
}
});
});
</script>
</html>

Javascript variable not changing inside onload function

this code always return me '3' in alert.
I select two files together (ones .mp4 format and second ones .zip format)
function readFile(input) {
var counter = input.files.length;
for(x = 0; x<counter; x++){
if (input.files && input.files[x]) {
var extension = input.files[x].name.split('.').pop().toLowerCase();
var reader = new FileReader();
reader.onload = function (e) {
urlss = 1;
if(extension == 'mp4'){
urlss = 2;
}else{
urlss = 3;
}
alert(urlss);
};
reader.readAsDataURL(input.files[x]);
}
}
}
<input type="file" id="files" name="files[]" accept=".png, .jpg, .jpeg, .zip, .mp4" onchange="readFile(this);" multiple />
That is because of var hoisting
The onload function calling after the for was ended and extension == last file extension
Try replace var with const:
function readFile(input) {
var counter = input.files.length;
for(let x = 0; x < counter; x++){
if (input.files && input.files[x]) {
const extension = input.files[x].name.split('.').pop().toLowerCase();
const reader = new FileReader();
reader.onload = function (e) {
urlss = 1;
if(extension == 'mp4'){
urlss = 2;
}else{
urlss = 3;
}
alert(urlss);
};
reader.readAsDataURL(input.files[x]);
}
}
}
Update
Please check the Webber's comment below.

Put .txt file in a textarea

I have this textarea:
<input id="inputOuvrirFichier" type="file" onchange="handleFiles(this.files)" name="files[]" accept=".txt">
I need to put the contents of a .txt file into this textarea.
This is my function :
function handleFiles(file){
document.getElementById("titre").click();
console.log(file);}
How can i get the text contain in the file please ? (Javascript)
Thanks.
JS, have not access to local on ur server, only throw ajax-request:
function readTextFile(file)
{
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;
$('#inputOuvrirFichier').text(allText)
}
}
}
rawFile.send(null);
}
You may use the FileReader API
function handleFiles(files) {
var i = 0;
var reader = new FileReader();
reader.onload = function() {
i++;
document.getElementById('result').innerHTML += this.result;
if (i < files.length)
reader.readAsText(files[i])
};
reader.readAsText(files[0]);
}
<input id="inputOuvrirFichier" type="file" onchange="handleFiles(this.files)" name="files[]" accept=".txt" multiple="">
<div id="result"></div>

How do I loop through a file, byte by byte, in JavaScript?

I need some help getting my head around how the file is accessed in JavaScript to do some operations on it.
I would like to loop through a file byte by byte using JavaScript.
I can already select which file I would like to read. And I can read preset byte of the file.
I've found this nice example on how to read a slice of a file here:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
Here is the snippet of code which I'm playing with:
<style>
#byte_content {
margin: 5px 0;
max-height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
#byte_range { margin-top: 5px; }
</style>
<input type="file" id="files" name="file" /> Read bytes:
<span class="readBytesButtons">
<button data-startbyte="0" data-endbyte="4">1-5</button>
<button data-startbyte="5" data-endbyte="14">6-15</button>
<button data-startbyte="6" data-endbyte="7">7-8</button>
<button>entire file</button>
</span>
<div id="byte_range"></div>
<div id="byte_content"></div>
<script>
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
document.getElementById('byte_content').textContent = evt.target.result;
document.getElementById('byte_range').textContent =
['Read bytes: ', start + 1, ' - ', stop + 1,
' of ', file.size, ' byte file'].join('');
}
};
var blob = file.slice(start, stop + 1);
reader.readAsBinaryString(blob);
}
document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
}
}, false);
</script>
Now I would like to loop through the file, four bytes at a time, but cannot seem to figure out how to do that. The reader does not seem to allow me to read more than once.
Once I can read from the file more than once, I should be able to iterate through it quite easily with something like this:
while( placemark != fileSize-4 ){
output = file.slice(placemark, placemark + 4);
console.log(output);
placemark = placemark + 5;
}
Thanks in advance!
Here is a link to a jsFiddle and plnkr version
I'm not sure it is what you wanted but maybe it can help, and anyway I had fun.
I tried setting reader and file vars as global :
var reader = new FileReader(), step = 4, stop = step, start = 0, file;
document.getElementById('files').addEventListener('change', load, true);
function load() {
var files = document.getElementById('files').files;
file = files[0];
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var result = evt.target.result;
document.getElementById('byte_content').textContent += result;
document.getElementById('byte_range').textContent = ['Read bytes: ', start, ' - ', start+result.length,
' of ', file.size, ' byte file'
].join('');
}
}
}
function next() {
if (!file) {
alert('Please select a file!');
return;
}
var blob = file.slice(start, stop);
reader.readAsBinaryString(blob);
start+= step;
stop = start+step;
}
function loop() {
if (!file) {
alert('Please select a file!');
return;
}
if (start < file.size) {
next();
setTimeout(loop, 50);
}
}
<input type="file" id="files" name="file" />Read bytes:
<span class="readBytesButtons">
<button onclick="next()">next</button>
<button onclick="loop()">loop</button>
</span>
<div id="byte_range"></div>
<div id="byte_content"></div>
I'd read the blob as an ArrayBuffer and use a DataView to read through the data
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
reader.onload = function(evt) {
var placemark = 0, dv = new DataView(this.result), limit = dv.byteLength - 4, output;
while( placemark <= limit ){
output = dv.getUint32(placemark);
console.log(' 0x'+("00000000" + output.toString(16)).slice(-8));
placemark += 4;
}
};
var blob = file.slice(start, stop + 1);
reader.readAsArrayBuffer(blob);
}
<input type="file" id="files" onchange="readBlob(0, 100)">
In the onload handler of FileReader, convert the result to string (toString()), then read 4 chars at a time with the string's slice method.
var contents = null;
reader.onload = function(){
contents = reader.result.toString();
}
var startByte = 0;
// read 4 bytes at a time
var step = 4;
// actual reading (doesn't alter the contents object)
console.log(contents.slice(startByte, step))
// update the next startByte position
startByte += step;

Reading multiple files with Javascript FileReader API one at a time

I'm using the FileReader API to read multiple files.
<html> <body>
<input type="file" id="filesx" name="filesx[]"
onchange="readmultifiles(this.files)" multiple=""/>
<div id="bag"><ul/></div>
<script>
window.onload = function() {
if (typeof window.FileReader !== 'function') {
alert("The file API isn't supported on this browser yet.");
}
}
function readmultifiles(files) {
var ul = document.querySelector("#bag>ul");
while (ul.hasChildNodes()) {
ul.removeChild(ul.firstChild);
}
function setup_reader(file) {
var name = file.name;
var reader = new FileReader();
reader.onload = function(e) {
var bin = e.target.result; //get file content
// do sth with text
var li = document.createElement("li");
li.innerHTML = name;
ul.appendChild(li);
}
reader.readAsBinaryString(file);
}
for (var i = 0; i < files.length; i++) { setup_reader(files[i]); }
}
</script> </body> </html>
The problem is that all files are read at the same time, and when the files have a total size (sum) that is very large, the browser crashes.
I want to read one file after another, so that the memory consumption is reduced.
Is this possible?
I came up with a solution myself which works.
function readmultifiles(files) {
var reader = new FileReader();
function readFile(index) {
if( index >= files.length ) return;
var file = files[index];
reader.onload = function(e) {
// get file content
var bin = e.target.result;
// do sth with bin
readFile(index+1)
}
reader.readAsBinaryString(file);
}
readFile(0);
}
I'm updating this question for the benefit of new users, who are looking for a solution to upload multiple files via the FileReader API, especially using ES.
Rather than manually iterating over each file, it's much simpler & cleaner to use Object.keys(files) in ES:
<input type="file" onChange="readmultifiles" multiple/>
<script>
function readmultifiles(e) {
const files = e.currentTarget.files;
Object.keys(files).forEach(i => {
const file = files[i];
const reader = new FileReader();
reader.onload = (e) => {
//server call for uploading or reading the files one-by-one
//by using 'reader.result' or 'file'
}
reader.readAsBinaryString(file);
})
};
</script>
This should read the files one by one:
function readmultifiles(files) {
var ul = document.querySelector("#bag>ul");
while (ul.hasChildNodes()) {
ul.removeChild(ul.firstChild);
}
// Read first file
setup_reader(files, 0);
}
// Don't define functions in functions in functions, when possible.
function setup_reader(files, i) {
var file = files[i];
var name = file.name;
var reader = new FileReader();
reader.onload = function(e){
readerLoaded(e, files, i, name);
};
reader.readAsBinaryString(file);
// After reading, read the next file.
}
function readerLoaded(e, files, i, name) {
// get file content
var bin = e.target.result;
// do sth with text
var li = document.createElement("li");
li.innerHTML = name;
ul.appendChild(li);
// If there's a file left to load
if (i < files.length - 1) {
// Load the next file
setup_reader(files, i+1);
}
}
Define the input using multiple property:
<input onchange = 'upload(event)' type = 'file' multiple/>
Define the upload function:
const upload = async (event) => {
// Convert the FileList into an array and iterate
let files = Array.from(event.target.files).map(file => {
// Define a new file reader
let reader = new FileReader();
// Create a new promise
return new Promise(resolve => {
// Resolve the promise after reading file
reader.onload = () => resolve(reader.result);
// Read the file as a text
reader.readAsText(file);
});
});
// At this point you'll have an array of results
let res = await Promise.all(files);
}
My complete solution is here:
<html> <body>
<input type="file" id="filesx" name="filesx[]"
onchange="readmultifiles(this.files)" multiple=""/>
<div id="bag"></div>
<script>
window.onload = function() {
if (typeof window.FileReader !== 'function') {
alert("The file API isn't supported on this browser yet.");
}
}
function readmultifiles(files) {
var reader = new FileReader();
function readFile(index) {
if( index >= files.length ) return;
var file = files[index];
reader.onload = function(e) {
// get file content
var bin = e.target.result;
// do sth with bin
readFile(index+1)
}
reader.readAsBinaryString(file);
}
readFile(0);
function setup_reader(file) {
var name = file.name;
var reader = new FileReader();
var ul = document.createElement("ul");
document.getElementById('bag').appendChild(ul);
reader.onload = function(e) {
var bin = e.target.result; //get file content
// do sth with text
var li = document.createElement("li");
li.innerHTML = name;
ul.appendChild(li);
}
reader.readAsBinaryString(file);
}
for (var i = 0; i < files.length; i++) { setup_reader(files[i]); }
}
</script> </body> </html>
I implemented another solution using modern JS (Map, Iterator). I adapted the code from my Angular application (originally written with some TS features).
Like Steve KACOU mentioned, we create a different FileReader instance for each file.
<input type="file" id="filesx" name="filesx[]"
onchange="processFileChange(this)" multiple=""/>
function processFileChange(event) {
if (event.target.files && event.target.files.length) {
const fileMap = new Map();
for (let i = 0; i < event.target.files.length; i++) {
const file = event.target.files[i];
const fileReader = new FileReader();
fileMap.set(fileReader, file);
}
const mapEntries = fileMap.entries();
readFile(mapEntries);
}
}
function readFile(mapEntries) {
const nextValue = mapEntries.next();
if (nextValue.done === true) {
return;
}
const [fileReader, file] = nextValue.value;
fileReader.readAsDataURL(file);
fileReader.onload = () => {
// Do black magic for each file here (using fileReader.result)
// Read the next file
readFile(mapEntries);
};
}
Basically this takes advantage of passing objects by reference to perpetuate the map with every iteration. This makes the code quite easy to read in my opinion.
Taking the best parts of these answers.
<input type="file" onchange="readmultifiles(this.files)" multiple />
<script>
function readmultifiles(files) {
for (file of files) {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.fileName = file.name;
reader.onload = (event) => {
const fileName = event.target.fileName;
const content = event.currentTarget.result;
console.log({ fileName, content });
};
}
}
</script>
You must instantiate a FileReader for each file to read.
function readFiles(event) {
//Get the files
var files = event.input.files || [];
if (files.length) {
for (let index = 0; index < files.length; index++) {
//instantiate a FileReader for the current file to read
var reader = new FileReader();
reader.onload = function() {
var result = reader.result;
console.log(result); //File data
};
reader.readAsDataURL(files[index]);
}
}
}
Try this
const setFileMultiple = (e) => {
e.preventDefault();
//Get the files
let file = [...e.target.files] || [];
file.forEach((item, index) => {
let reader = new FileReader();
reader.onloadend = () => {
console.log("result", reader.result);
};
reader.readAsDataURL(file[index]);
});
};

Categories

Resources