Pass javascript variable to .js file

Hello all,

I’m having trouble opening a text file using a .js file.
The webpage contains several small images which - on a ‘onmouseover’ instruction - are displayed full size.
Each image has its own text file, which I need to display in the div id=fileContents.

Using the following HTML code I can choose the correct text file:
HTML:

<script>
    var txtfile = "file0.txt";
</script>

<body>
    <div id="fileContents" ></div>
    <input type="file"  id="tekstfile"><script src="app.js"></script>
</body>

APP.JS contains:

 document.getElementById(tekstfile).onchange = function() {  
  	document.getElementById("fileContents").textContent = "";
 	var file = this.files[0];
 	var reader = new FileReader();
 	reader.onload = function(progressEvent) {
 		var lines = this.result.split('\n');
 		for(var line = 0; line < lines.length; line++) {
 			console.log(lines[line]);
 			if (line > "-1") {
 				document.getElementById("fileContents").innerText += lines[line];
 			} else {
 				document.getElementById("fileContents").textContent = lines[line];
 			}
 		}
 	}
 	reader.readAsText(file);
 }

The var txtfile changes along with every image change. So I would like to use the value of var txtfile to open the text file instead of the input value.

1 Like

Hi Shurlock, I’d love to help you out, but can you do me a favor and invest a few minutes in re-reading and organizing your question before I invest my time in helping you? In particular: it’d be very helpful if you used code blocks and indented your code. You can put a tripple tick (```) at the top and bottom of your code to style it. Also there’s at least one sentence that is difficult to read.

Hi Josh,
Thanks for the tips, hope all is now a bit more clear.

In short:

  • var txtfile alwas contains the correct text filename
  • I do not want to use the input statement, I want to use the value of var txtfile in the .js file
  • document.getElementById(txtfile).onchange = function() will not work. What do I need to adjust?

Hope this makes clear what my problem is.

Wow, this is beautiful. Thank you, Shurlock!

So let me recap to see if I understand, then I’m going to suggest a small change.

My understanding:

You have a collection of images and text files. Each image has a corresponding text file. When the user hovers over an image, you want to display its text from its corresponding text file.

When the user hovers over the image, the txtfile variable is automatically changed to contain the correct filename, so we don’t have to worry about that.

Your code currently reads the file from the <input id=tekstfile> input, but you want it to read the file from the txtfile variable.

You want <div id="fileContents"></div> to contain the contents of txtfile

Is this correct?

Ideas/solution

Write and name a function that will update fileContents. You’ve already written all the code, just a few changes to make it into a function:

function displayTextFile(filename) {
 	document.getElementById("fileContents").textContent = "";
 	var file = filename; // only change
 	var reader = new FileReader();
 	reader.onload = function(progressEvent) {
 		var lines = this.result.split('\n');
 		for(var line = 0; line < lines.length; line++) {
 			console.log(lines[line]);
 			if (line > "-1") {
 				document.getElementById("fileContents").innerText += lines[line];
 			} else {
 				document.getElementById("fileContents").textContent = lines[line];
 			}
 		}
 	}
 	reader.readAsText(file);
}

Now you just need to call your function at the right time. There’s two ways you can do this.

First idea: you must have some code that updates the txtfile variable every time the user hovers over an image. What is that code? You can simply call your new function from that code… ex:

txtfile = "file0.txt";
displayTextFile(txtfile);

Maybe I missunderstood, and the vaue of txtfile never changes. If so, simply call displayTextfile(txtfile) as the last line in App.js.

Second idea: we can use setInterval, but that’s less than ideal, lets see if we can do it right.

Hi again Josh,

Your recap is perfect. The variable for the text files in indeed being adjusted with each movement over the thumbnails.

For the sake of ‘easy reading’, I have inserted the app.js into the HTML script area.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script>
var foto0 = new Image();
var foto1 = new Image();

foto0.src = "images/foto0.jpg";
foto1.src = "images/foto1.jpg";

var tekst = "images/foto";
var tekstfile = tekst + "0.txt";

function ShowLargeFoto(ChangeToFoto) {
	eval("document['fotos'].src = foto" + ChangeToFoto + ".src");
	tekstfile = tekst + ChangeToFoto + ".txt";
	displayTextFile(tekstfile);									
}

function displayTextFile(tekstfile) {
 	document.getElementById("fileContents").textContent = "";
 	var file = tekstfile; 						// only change
 	var reader = new FileReader();
 	reader.onload = function(progressEvent) {
 		var lines = this.result.split('\n');
 		for(var line = 0; line < lines.length; line++) {
 				document.getElementById("fileContents").innerText += lines[line];
 		}
 	}
 	reader.readAsText(file);
}
</script>
</head>

<body>
<div style="position: absolute; top: 50px; left: 9px; width: 162px; height: 860px; z-index: 2">
	<a onmouseover="ShowLargeFoto('0')" href="#"><img align="center" src="images/foto0_small.jpg" width=75 height=100></a><br>Foto0<br><br>
	<a onmouseover="ShowLargeFoto('1')" href="#"><img align="center" src="images/foto1_small.jpg" width=75 height=100></a><br>Foto1<br><br>
</div>

<!-- DISABLED; app.js is now intergrated in this HTML script section -->
<!--	<input type="file"  id="tekstfile"><script src="app.js"></script>  -->

<div class="center" style="position: relative; left: 500px; width: 800px; top:6px; height:800px">
	<img border="1" src="images/foto0.jpg" name=fotos width="auto" height="630">
</div>

<div id="fileContents" style="position: absolute; left: 1250px; width: 400px; top:60px; height:500px; border: solid yellow 4px;">
</div>

</body>
</html>

Opening the webpage and viewing the console shows an error:
TypeError: Argument 1 of FileReader.readAsText is not an object.

Hope you will be able to help me out with this.
Thanks in advance for the effort.

Sweet, glad I’m understanding right. Thanks for providing your full code here, this will make things easier if you’re having more issues later.

When you get these kinds of errors (unknown method, unexpected argument, etc), one of the best things to do is take a look at the documentation. Here’s documentation for the FileReader.readAsText() method: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsText

It looks like FileReader.readAsText() expects a Blob or a File as its argument. You are currently passing a string (my apologies, I think this was my error because I didn’t know the type of the argument when I made the change). Here’s the docs for File: https://developer.mozilla.org/en-US/docs/Web/API/File/File

Unfortunately, if you look at the arguments for File, you’ll see that the first argument is the contents of the file. I don’t think this is very helpful.

In order to do the right thing here, you’re going to have to read the file. How you read the file depends on how you are hosting your website. Are you viewing your html file using the path on your local computer, or do you have a webserver set up? Concretely, in your browser’s address bar, do you see something like file://c:/home/yourusername/Desktop/yourhtmlfile.html (viewing a local file) or http://localhost or http://127.0.0.1 (hosting website behind web server)? The part at the very beginning is what matters, does it show http://, file://, or c:/?

Basically, all the caveats you see about chrome not supporting file:// are what I’m concerned about and trying to discuss with you: https://stackoverflow.com/questions/14446447/how-to-read-a-local-text-file. The browser protects you as a user. If any webpage could just read any file from your computer, that’d be very dangerous! So if you want your webpage to read a file from your computer, things might get a little tricky. Lets discuss how you’ve got your hosting set up, and then we can discuss a solution.