Trying to make a button after an import statement in javascript - javascript

I am trying to program something that reads in file data, stores specific information in an array, then exports that array to a different javascript file. In the javascript file, in which I import the array, I am trying to create a button that has text-based off of the array.
The problem I am having is that after I import the array and initialize the button, it will not appear. However, if I don't import anything and have the same code to initialize my button (but with me writing random stuff for the button's text), it works fine. Also, I am sure that the array is being exported/imported fine because if I use console.log(names[0]) in the file I export it to, it will output the correct value. To clarify, if I include the import statement, I do not get an error, but the button just will not appear on the Chrome tab that it should appear on.
My first javascript file (why.js):
import fs from 'fs';
let names = [];
var lines = fs.readFileSync('input.txt').toString().split("\n");
for(let line = 0; line < lines.length; line++){
let word = "";
let info = 0;
for(let ind = 0; ind < lines[line].length; ind++){
word += (lines[line]).charAt(ind);
if((lines[line]).charCodeAt(ind) < 32 || (lines[line]).charCodeAt(ind) > 122){
info++;
if(info == 1){
names.push(word);
}
word = "";
}
}
}
export { names };
my second javascript file (buttons.js):
//if I don't include this line, the button will initialize and appear
import { names } from './why.js'
let button = document.createElement('button');
button.innerHTML = 'artichoke';
//i want it to be: button.innerHTML = names[0];
document.body.appendChild(button);
console.log(names[0]);
I'm not sure if this is important, but here is my html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>something random here for now ig</h1>
<script src="why.js"></script>
<script src="buttons.js"></script>
</body>
</html>
TLDR: After I import an array from my first javascript file to another, I am unable to create any button at all (though the code runs without error), but if I don't import anything, the button is created fine and appears.
Thank you for reading, and I would appreciate any feedback or tips :)

Related

My Extensions Google Chrome Does not Work?

I create a simple code to extract URL from a website
but it's not working when I click on icon extensions
My js code
var el = document.getElementById('myPopup');
el && el.addEventListener('click', yourFunction, false);
function yourFunction() {
let x = document.querySelectorAll("a");
let myarray = [];
for (let i = 0; i < x.length; i++) {
let nametext = x[i].textContent;
let cleantext = nametext.replace(/\s+/g, " ").trim();
let cleanlink = x[i].href;
myarray.push([cleantext, cleanlink]);
}
function make_table() {
let links_table = "<table><thead><th>Name</th><th>Links</th></thead><tbody>";
for (let i = 0; i < myarray.length; i++) {
links_table += "<tr><td>" + myarray[i][0] + "</td><td>" + myarray[i][1] + "</td></tr>";
}
let w = window.open("");
w.document.write(links_table);
console.log(w);
console.log(links_table);
}
make_table();
}
yourFunction();
My HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<dev>
<button id="myPopup">Clickme</button>
</dev>
<script src="popup.js"></script>
</body>
</html>
when i click on Clickme the url not show me just empty table
can you tell me where is the Error?
video
imgur.com/a/0OS60qG
The error happens since the popup script does not have access to the list of "a" tags. When you ran it on the browser console it works cause you are manipulating the page content, meanwhile, on the popup, it only interacts with the popup.html page.
Content scripts should be the only scripts able to manipulate the page content, so to fix that you probably should send a message to a content script when clicking on the button, so the content script can scrap the links and send them as a response to the popup or output as you want.
This other question may help you to see how to send messages between files:
How to send the message from popup.html to content script?

localStorage not working properly/localStorage overwriting itself

I'm attempting to create a simple to-do list and I've encountered two problems:
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage.
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
Despite that, the items displayed from the input fields are from the previous localStorage, which no longer exists (I really hope this makes sense).
const inputEl = document.getElementById("inputEl")
const submitBtn = document.getElementById("submit")
const clearBtn = document.getElementById("clearBtn")
const todoListContainer = document.getElementById("todoList")
const taskContainer = document.querySelector(".task")
const cancelBtn = document.querySelector(".cancelBtn")
const doneBtn = document.querySelector(".doneBtn")
const errorMsg = document.querySelector(".error")
let localStorageContent = localStorage.getItem("tasks")
let tasksItem = JSON.parse(localStorageContent)
let tasks = []
function createTask() {
if (inputEl.value.length != 0) {
const newDiv = document.createElement("div")
newDiv.classList.add("task")
const newParagraph = document.createElement("p")
const newCancelBtn = document.createElement("button")
newCancelBtn.classList.add("cancelBtn")
newCancelBtn.textContent = "X"
const newDoneBtn = document.createElement("button")
newDoneBtn.classList.add("doneBtn")
newDoneBtn.textContent = "Done"
todoListContainer.appendChild(newDiv)
newDiv.appendChild(newParagraph)
newDiv.appendChild(newCancelBtn)
newDiv.appendChild(newDoneBtn)
//^^ Creating a container for a new task, with all its elements and assigning the classes^^
tasks.push(inputEl.value)
inputEl.value = ""
for (let i = 0; i < tasks.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasks))
newParagraph.textContent = JSON.parse(localStorageContent)[i]
}
errorMsg.textContent = ""
} else {
errorMsg.textContent = "You have to type something in!"
errorMsg.classList.toggle("visibility")
}
}
submitBtn.addEventListener("click", () => {
createTask()
})
clearBtn.addEventListener("click", () => {
localStorage.clear()
})
HTML code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script>
<title>To-do list</title>
</head>
<body>
<h2 class="error visibility"></h2>
<div id="todoList">
<h1>To-Do List</h1>
<input type="text" name="" id="inputEl" placeholder="Add an item!">
<button type="submitBtn" id="submit">Submit</button>
<button id="clearBtn">Clear list</button>
<div class="task">
</div>
</div>
</body>
</html>
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage
That is because you are rendering the HTML only after the click event and not on page load. To render the HTML for existing tasks stored in the localStorage you have to write a code that loops over your existing tasks in the tasksItem and applies the rendering logic to it.
I would suggest splitting the rendering code from your createTask() function and create a new function for it (for example renderTask()), then you can use it inside a loop on page load and also call the function once a new task is created in the createTask() function.
window.addEventListener('load', (event) => {
// Your read, loop and render logic goes here
})
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
That's because you are actually overriding the tasks in the localStorage. To keep existing tasks, you have to use your tasksItem variable instead of the blank tasks array to create your tasks in and save them to the localStorage.
So, instead of:
tasks.push(inputEl.value)
You would use:
tasksItem.push(inputEl.value)
The same goes for:
for (let i = 0; i < tasksItem.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasksItem))
// …
}

Take line from .txt file and display in html page

I want to make a small project for my girlfriend and what I had in mind was to have an HTML page that says "I Love". On the press of a button the website would display under the text a random line from a text document I have made with all the things I love about her. Example:
What I managed
So I have managed to make a page with only the "I LOVE" and adding the text under it when I click the button. But I would like it to be able to take a random line from a .txt file where each line would be one line of text it would randomly choose and display on the html.
Thanks
You cant load from files on server from client side cuz that would be a huge no-no when it comes to security. Just imagine that. You need some back-end (server side) language like PHP.
Here is the most basic PHP code ( with comments ) that does what you want:
<?php
// you put your filename here ( obviously )
$fileName = "girl.txt";
// opening and reading file
$fileH = fopen( $fileName, "r") or die("Unable to open file!");
$fileCont = fread( $fileH,filesize( $fileName));
fclose($fileH);
// split text into lines
$lines = explode( "\r\n", $fileCont);
$numOfLines = count($lines);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- import math module -->
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>
</head>
<body>
<!-- prints random choice to html code -->
<h1>I Love</h1>
<button>Click Me!</button>
<script>
// print php array into js
<?php echo "lines = ['".join("', '", $lines)."'];\n"; ?>
maxLineNum = <?php echo $numOfLines; ?>;
// on button click you get random msg in h1
document.querySelector("button").addEventListener( "click", ()=>{
randNum = math.floor( math.random()*maxLineNum );
document.querySelector("h1").textContent = "I love " + lines[randNum];
} );
</script>
</body>
</html>
I am new to JavaScript, but I would try storing the snippets in an array in the JS itself rather than putting them in a separate text file than then needs to be accessed and processed before it can be used.
JS:
const niceSnippets = [
‘your smile’,
‘your sense of humour’, // repeat for as many snippets as you can think of
‘you’
];
const chooseSnippet = () => { niceSnippets[Math.floor(Math.random()*niceSnippets.length)]; }
const changeSnippet = () => { document.getElementById('snippetDisplay').innerText = chooseSnippet(); }
with the relevant elements in the HTML updated with id and onclick:
<p id=“snippetDisplay”></p>
<button onclick=“changeSnippet()”>Click Me!</button>

Why isn't html running javascript I import when I use import-export

My code works fine when I add my module straight into the html code, but it won't load it when I try to first import the module to a different javascript file.
I've tried exporting everything, from my module.
HTML:
<html>
<head>
<title>
Hello world
</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Tradingpost, done by no css gang.</h1>
<div id="sidenav">Here be the links to other pages</div>
<br>
<footer id="footer">
Done whenever. Copyright is mine.
</footer>
<script src="js/app.js"></script>
</body>
</html>
app.js:
import * as sidebar from "./visualModules/sidebarmodule"
function cumulator() {
sidebar.createSidebar()
}
sidebarmodule.js:
function sidebarAdder(pages) {
const sidebar = document.getElementById("sidenav")
const list = document.createElement("UL")
for(index = 0; index < pages.length; index++) {
const ul = document.createElement("LI")
const a = document.createElement("A")
a.setAttribute("href", "/" + pages[index])
a.innerHTML = "" + pages[index]
ul.appendChild(a)
list.appendChild(ul)
}
sidebar.appendChild(list)
}
export function createSidebar() {
var pages = [
"home",
"tradingpost"
]
sidebarAdder(pages)
}
It should add elements to the div. But it wont do it unless I straight up use the sidebarmodule.js. I want to do it through the app.js
EDIT
Found the problem!
Didn't initialize index in the for loop.
EDIT2
And the type="module" which needed to be added
When you load your app.js in your html file, try to add:
<script type="module" src="js/app.js"></script>
That should work when you want to use ESModules. But please update us regardless :)
Update:
Ok after creating a project myself using your HTML and JS, I found a few errors.
First: When using ESModules, you can't use any functions in the JS through your HTML, you will have to inject everything from the app.js.
index.html:
<body>
<div id="sidenav">
Here be the links to other pages
</div>
<br>
<footer id="footer">
Done whenever. Copyright is mine.
</footer>
<script type="module" src="js/app.js"></script>
app.js:
import { createSidebar } from './visualModules/sidebarmodule.js';
cumulator();
function cumulator() {
createSidebar()
}
Notice two things: at the end of the import, since we are not using a compiler, the modules do not recognize files without their extension. So I had to add .js to sidebarmodule. Secondly, I had to invoke cumulator function within the app.js file (like I said earlier, you cannot use any module functions outside their scope. There are no global variables with ESModules).
sidebarmodule.js:
function sidebarAdder(pages) {
const sidebar = document.getElementById("sidenav")
const list = document.createElement("UL")
for(var index = 0; index < pages.length; index++) {
const ul = document.createElement("LI")
const a = document.createElement("A")
a.setAttribute("href", "/" + pages[index])
a.innerHTML = "" + pages[index]
ul.appendChild(a)
list.appendChild(ul)
}
sidebar.appendChild(list)
}
export function createSidebar() {
var pages = [
"home",
"tradingpost"
]
sidebarAdder(pages)
}
You did not declare index inside your for loop, so I just added a var.
Hope this helps.
import is asynchronous in Javascript (in a browser, not Node.js) so you're calling createSidebar() before the module is loaded. You can use import to return a promise so you can execute code once it is completed.
Remove the embedded Javascript from your html, but leave the link to app.js. Then change app.js to this...
import("./visualModules/sidebarmodule")
.then((sidebar) => {
sidebar.createSidebar();
});

Issue Storing File Paths in Javascript Array from C#

I am trying to store all of file paths from a string array in C# into a Javascript array and it works and stores them all in the array but the path's slashes are removed so the file path doesn't read as normal and produces an error. The file path is shown in the following and as you can see in the end of the path everything collides together because the slashes disappear.:
If the slashes were in there then the file path should be able to be read in my code sample I will include which I have tested with file paths. I was just wondering how to, in my code, have the slashes retained in javascript.
What my code does is pass in an array of strings seperated by a semicolon from c# razor code in MVC and then puts each one in an array in Javascript and this is where it strips the slashes. Then the image is displayed using URL.Content and the file path.
ANY HELP IS APPRECIATED!
Code
<!DOCTYPE html>
<html>
<head>
#model Tuple
<string, string[]>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>My ASP.NET Application</title>
<script src="//code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
</head>
<body>
<div style="width:800px;height:400px;border:3px solid #000;margin:0
auto;margin-top:70px;position:relative;">
<img src="" style="width:100%;height:100%;" id="img" />
<p style="position:absolute;top:45%;font-
size:22px;color:#fff;left:10px;cursor:pointer;" id="left">
< </p>
<p style="position:absolute;top:45%;font-
size:22px;color:#fff;right:10px;cursor:pointer;" id="right">></p>
</div>
</body>
</html>
<script type="text/javascript">
var arr = [];
var first = "#Model.Item1";
counter = 0;
#foreach(string i in Model.Item2) {
<
text > arr.push("#i") < /text>
}
$('#right').click(function() {
if (counter == 0) {
} else {
counter--;
}
});
$('#left').click(function() {
if (counter == 0) {
} else {
counter--;
}
});
var image = document.getElementById("img");
image.src = "#Url.Content("~/Practice/Images / ")" + arr[0];
</script>
There is problem with the way you populate the arr object. Somehow javascript escape sequence removes the slashes. Remove this #foreach(string i in Model.Item2) loop and You can directly assign value to arr as below.
var arr = #Html.Raw(Json.Encode(Model.Item2));

Categories