When I run my snippet (shown below), it replace the dashes (-), the single quote, and the double quote with �.
var button = document.querySelector('#fileInput + button');
var input = document.getElementById('fileInput');
var text = null;
input.addEventListener("change", addDoc);
button.addEventListener("click", handleText);
function addDoc(event) {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(e) {
text = reader.result;
button.removeAttribute("disabled");
};
reader.onerror = function(err) {
console.log(err, err.loaded, err.loaded === 0, file);
button.removeAttribute("diabled");
};
a = reader.readAsText(event.target.files[0]);
console.log(a);
}
function handleText() {
addtoPreviousOutput();
changeOutputParagraph(text);
button.setAttribute("disabled", "disabled");
}
function changeOutputParagraph(newText) {
var element = document.getElementById("output");
element.innerHTML = newText;
}
function addtoPreviousOutput() {
var previousOutput = document.getElementById("output").innerHTML;
var previousOutput_sOutput = document.getElementById("previousOutput").innerHTML + "<br />";
console.log(previousOutput);
console.log(previousOutput_sOutput);
document.getElementById("previousOutput").innerHTML = previousOutput_sOutput + previousOutput;
}
<p id="previousOutput"></p>
<p id="output"></p>
<input type="text" id="textInput" onkeypress="getText(event)" />
<input type="file" id="fileInput" accept="text/*" />
<button type="button" id="addDoc">Add Document</button>
Why is that and how do I fix it?
Edit
I get this when I run my file which is 176 lines and 22 KB. Note: This isn't all of the text.
readAsText reads the text as utf-8 by default. The reason you see � instead of your expected characters is because your text file is not utf-8 encoded.
You can pass the encoding of your file to readAsText to properly read the text.
e.g. for latin 1
a = reader.readAsText(event.target.files[0], 'ISO-8859-1');
A FileReader can only read one file at the time, however you're trying to read the file twice:
reader.readAsText(event.target.files[0]);
console.log(reader.readAsText(event.target.files[0]));
There's no actual reason for you to do that. Just store the first read result - and print the data that you've already read.
Related
I wrote a function to read HTML from a file and set the innerHTML of a certain div to equal the HTML inside the file, as a kind of save/load system. This used to work fine, however after a browser update I am getting the error seen in the title.
HTML:
<div id="target">
<button onclick="saveDiv()">Save</button>
<button onclick="loadDiv()">Load</button>
<input id="file" type="file" style="hidden">
<input>
</div>
JS:
const div = document.getElementById('target')
function saveDiv() {
var divContent = div.innerHTML.toString();
var ran = (Math.random() + 1).toString(36).substr(2, 8)
var fileName = `${ran}.txt`;
download(fileName, divContent);
}
function download(name, content) {
var e = document.createElement('a');
e.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content));
e.setAttribute('download', name);
e.style.display = 'none';
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
function loadActors() {
document.getElementById('file').click();
var file = document.getElementById('file').files[0];
var r = new FileReader();
r.onload = (function(reader) {
return function() {
var contents = reader.result;
div.innerHTML = contents;
}
})(r);
r.readAsText(file);
}
I think what may be happening is that the FileReader is trying to read the file before the user has selected it, but I'm not exactly sure. Anyone know what may be happening here?
Edit: Seems that if I select the file after the error then click the load button again it runs fine. How would I make it only run after the user has selected the file?
I want to extract a string from a text file, convert it to a word scrambler (I figured out that part) and output it in another text file.
I found some code to input a text file and extract the text:
<html>
<h4>Select un file con .txt extension</h4>
<input type="file" id="myFile" accept=".txt" />
<br /><br />
<div id="output"></div>
<script>
var input = document.getElementById("myFile");
var output = document.getElementById("output");
input.addEventListener("change", function () {
if (this.files && this.files[0]) {
var myFile = this.files[0];
var reader = new FileReader();
reader.addEventListener("load", function (e) {
output.textContent = e.target.result;
});
reader.readAsText(myFile);
}
});
</script>
</html>
Input text and extract a text file
<html>
<div>
<input type="text" id="txt" placeholder="Write Here" />
</div>
<div>
<input type="button"id="bt"value="Save in a File"onclick="saveFile()"/>
</div>
<script>
let saveFile = () => {
const testo = document.getElementById("txt");
let data = testo.value;
const textToBLOB = new Blob([data], { type: "text/plain" });
const sFileName = "Testo.txt";
let newLink = document.createElement("a");
newLink.download = sFileName;
newLink.href = window.URL.createObjectURL(textToBLOB);
newLink.style.display = "none";
document.body.appendChild(newLink);
newLink.click();
};
</script>
</html>
But I don't know how to output a string in the first code or how to connect it to the second code. Could someone please show me how to do it or explain how these codes work so that I could try to do it myself in JavaScript?
I will comment each line of JavaScript, that should help you understand.
<script>
/*This creates a global variable with the HTML element input in it. */
var input = document.getElementById("myFile");
/*This creates a global variable with the HTML element div with id output in it. */
var output = document.getElementById("output");
/* this 2 lines are used to set the source and the destination.
The first will get where you put your file, in this case it's the input element.
The second will get the div which content will be replaced by the content of your txt file. */
/* Here we tell to our input element to do something special when his value changes.
A change will occur for example when a user will chose a file.*/
input.addEventListener("change", function () {
/* First thing we do is checking if this.files exists and this.files[0] aswell.
they might not exist if the change is going from a file (hello.txt) to no file at all */
if (this.files && this.files[0]) {
/* Since we can chose more than one file by shift clicking multiple files, here we ensure that we only take the first one set. */
var myFile = this.files[0];
/* FileReader is the Object in the JavaScript standard that has the capabilities to read and get informations about files (content, size, creation date, etc) */
var reader = new FileReader();
/* Here we give the instruction for the FileReader we created, we tell it that when it loads, it should do some stuff. The load event is fired when the FileReader reads a file. In our case this hasn't happened yet, but as soon as it will this function will fire. */
reader.addEventListener("load", function (e) {
/* What we do here is take the result of the fileReader and put it inside our output div to display it to the users. This is where you could do your scrambling and maybe save the result in a variable ? */
output.textContent = e.target.result;
});
/* This is where we tell the FileReader to open and get the content of the file. This will fire the load event and get the function above to execute its code. */
reader.readAsText(myFile);
}
});
</script>
With this I hope you'll be able to understand the first part of this code. Try putting the second part of your code instead of output.textContent and replacing data with e.target.result, that should do what you wish, but I'll let you figure it out by yourself first, comment on this answer if you need further help !
Here's a codepen with working and commented code:
https://codepen.io/MattDirty/pen/eYZVWyK
I want to read content of a txt or HTML file (some HTML element saved in before) and add them to current page. (like importing template in sliders). I found this code That's work correctly:
var input = document.getElementById("myFile");
var output;
document.getElementById('myFile').addEventListener("change", function() {
if (this.files && this.files[0]) {
var myFile = this.files[0];
var reader = new FileReader();
reader.addEventListener('load', function(e) {
document.getElementById("aDivToShowResult").innerHTML = e.target.result;
});
reader.readAsText(myFile);
}
});
<input type="file" id="myFile">
<div id="aDivToShowResult">
</div>
But my content contain UTF-8 characters!!
(my page totally has UTF-8 charset but Note that the page does not reload when adding code!!
also the txt file saved in UTF-8)
how can I read file and its content(and add to DOM) by UTF-8 charset by JS??
If this is not possible, is there a library or other code to suggest?
You did great, you just have one tiny mistake: if you do innerHTML it will expect to receive some HTML. But you want to add text, right? Then you have to use the method: element.innerText = 'your text'
It's different because the later generates a text node, while the first will try to parse some HTML and add it to the DOM as Element Nodes.
Here's some reference:
innerHTML
innerText
var input = document.getElementById("myFile");
var output;
document.getElementById('myFile').addEventListener("change", function() {
if (this.files && this.files[0]) {
var myFile = this.files[0];
var reader = new FileReader();
reader.addEventListener('load', function(e) {
document.getElementById("aDivToShowResult").innerText = e.target.result;
});
reader.readAsText(myFile);
}
});
<input type="file" id="myFile">
<div id="aDivToShowResult"></div>
I am trying to do a Sha256 on a file in Javascript. I used FileReader(HTML5) to read in a file. I use the readAsBinaryString function in the FileReader to pass in the images file. Then on the FileReader.onload function I pass in the evt.target.result to the SHA256 method in the CryptoJs API. I am able to successfully get a hash value but it is not correct. When I pass in a text file, it works fine but not image file.
Code(Should be able to copy the code below to a HTML file and run it on firefox - press the "entire file" button):
<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><BR>
<div id="byte_content"></div><BR>
<div id="crypto_sha256"></div>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha256.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js"></script>
<script>
var sha256;
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('');
//**UPDATED SOLUTION: Since its binary data, the message needs to be converted from string to bytes using Latin1**
sha256.update(CryptoJS.enc.Latin1.parse(evt.target.result));
var hash = sha256.finalize();
document.getElementById('crypto_sha256').textContent = ['SHA-256: ', hash].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');
sha256 = CryptoJS.algo.SHA256.create();
readBlob(startByte, endByte);
}
}, false);
</script>
Sample outputs:
Testing a "text" file:
SHA256 generated by Javascript:
78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09
SHA256 generated by cygwin on the same file:
$ sha256sum Phillips.txt
78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09 *SomeTestFile.txt
Testing a "binary" file(pdf):
SHA256 generated by Javascript:
57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605
SHA256 generated by cygwin on the same file:
$ sha256sum Smoke\ Detector\ Brochure.pdf
57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605 *Smoke Detector Brochure.pdf
I know this question is quite old but I figured I'd share what I know anyways.
You can do this more easily by doing what I discuss in this answer https://stackoverflow.com/a/17848266/2226207
Basically you can include components/lib-typedarrays-min.js and then do the following in code.
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
var wordArray = CryptoJS.lib.WordArray.create(e.target.result);
var hash = CryptoJS.SHA256(wordArray);
}
};
var blob = file.slice(start, stop + 1);
reader.readAsArrayBuffer(blob);
I haven't tested the above solution but it should work fine.
Here is a simple solution found : https://code.google.com/p/crypto-js/issues/detail?id=62
When you pass a string to a hasher, it's converted to bytes using UTF-8. That's to ensure foreign characters are not clipped. Since you're working with binary data, you'll want to convert the string to bytes using Latin1.
sha256.update(CryptoJS.enc.Latin1.parse(evt.target.result));
I have an HTML file that is using Javascript to do file I/O operations on a .txt file, via an ActiveXObject (only works in Internet Explorer, on Windows OS).
There is a text input box on the HTML page, and a button. The button calls a function onclick to write the text entered to the end of the .txt file. There is also a textarea on the HTML page, in which the modified contents of the .txt file are copied and pasted into. All of this is working so far...
So, I want to insert tabs and new-lines into the .txt file, from my HTML page with Javascript. I am using this line to copy the .txt file contents into the textarea, initialized in a variable:
var newText = oldText + "\n" + document.getElementById("userInput").value;
Of course, the escape character \n works on the HTML page, and not in the .txt file...
So how do I encode new lines, and tabs as well, into a parsable format for the .txt file? I have tried using the escape() method on ANSI values found here, and on ASCII values found here, but with no luck.
Here is my code so far:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>New Web Project</title>
</head>
<body>
<p>
Enter some text here:
<input type = "text" id = "userInput" />
</p>
<input type = "button" value = "submit" onclick = "main();" />
<br />
<hr />
<br /><br /><br />
<textarea id = "textHere" rows = 25 cols = 150></textarea>
<script type = "text/javascript">
// executes all code from this function to prevent global variables
function main()
{
var filePath = getThisFilePath();
var fileText = readFile(filePath);
writeFile(filePath, fileText);
} // end of function main
function getThisFilePath()
{
var path = document.location.pathname;
// getting rid of the first forward-slash, and ending at the last forward-slash to get rid of file-name
var correctPath = path.substr(1, path.lastIndexOf("/") );
var fixedPath = correctPath.replace(/%20/gi, " "); // replacing all space entities
return fixedPath;
} // end of function getThisFilePath
function readFile(folder)
{
var fso = "";
var ots = "";
var oldText = "";
try
{
fso = new ActiveXObject("Scripting.FileSystemObject");
// in the same folder as this HTML file, in "read" mode (1)
ots = fso.OpenTextFile(folder + "writeToText.txt", 1, true);
oldText = ots.ReadAll();
ots = null;
fso = null;
}
catch(e)
{
alert("There is an error in this code!\n\tError: " + e.message);
exit(); // end the program if there is an error
}
return oldText;
} // end of function readFile
function writeFile(folder, oldText)
{
var fso = "";
var ots = "";
var newText = oldText + "\n" + document.getElementById("userInput").value;
try
{
fso = new ActiveXObject("Scripting.FileSystemObject");
// in the same folder as this HTML file, in "write" mode (2)
ots = fso.OpenTextFile(folder + "writeToText.txt", 2, true);
ots.Write(newText);
ots.Close();
ots = null;
fso = null;
}
catch(e)
{
alert("There is an error in this code!\n\tError: " + e.message);
exit(); // end the program if there is an error
}
setText(newText); // with the function below
} // end of function writeFile
// called from the function writeFile
function setText(textFile)
{
document.getElementById("textHere").value = textFile;
} // end of function setText
</script> <!-- end of javascript -->
</body>
</html>
Windows expects "\r\n" as linebreaks. I'm quite sure you would find them in your textarea's value as well (after hitting enter). They will get automatically inserted when you set a value with "\n", and most libraries (like jQuery) do replace them with "normal" linebreaks when reading the value.
However, I would expect a file read/write with only "\n" to work, and when you load the file's text into your textarea they should show up. MS Notepad might have problems showing them.