Selecting Dropdown option, change h1 with javascript - javascript

I am very new to coding and couldn't find solution with if condition for this.
I know how I can do it with html code and options, but this time I need to make it with arrays and if function.
Basically I just need a dropdown with languages (which I made) and then when I click on specific language (for example, English) - I need to change html h1 to "Hello!", when I click Latvian "Labdien" etc.
Basically I need to write a proper if function, hope you could tell me what's wrong there.
const select = document.getElementById("select"),
arr = ["Latvian", "English", "Russian"];
for (var i = 0; i < arr.length; i++) {
var option = document.createElement("OPTION"),
txt = document.createTextNode(arr[i]);
option.appendChild(txt);
option.setAttribute("value", arr[i]);
select.insertBefore(option, select.lastChild);
}
if (arr[0] = "Latvian") {
document.getElementById("heading").innerHTML = "Labdien!";
} else if (arr[1] == "English") {
document.getElementById("heading").innerHTML = "Hello!";
} else if (arr[2] == "Russian") {
document.getElementById("heading").innerHTML = "Добрый день!";
}
<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>JavaScript Dropdown</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1 class="heading" id="heading"></h1>
<select class="drop" id="select"></select>
<script src="./main.js"></script>
</body>
Still figuring out whats wrong with if statement, there is some problem in :
if(arr[0] == "Latvian")
else if(arr[1] == "English")
else if(arr[2] == "Russian").
Or maybe I need to call a function and then place it onchoice in HTML? Help.. been googling and youtubing all day

You can add a change event listener to the select element. Also, you can use the index of each language as the value of the select options, and use the same array when set the h1 inner HTML:
var select = document.getElementById("select");
var arr = [
{ id: 1, language: 'Latvian', title: 'Labdien!' },
{ id: 2, language: 'English', title: 'Hello!' },
{ id: 3, language: 'Russian', title: 'Добрый день!' }
];
for (var i = 0; i < arr.length; i++) {
var option = document.createElement("OPTION");
var txt = document.createTextNode(arr[i].language);
option.appendChild(txt);
option.setAttribute('value', arr[i].id);
select.insertBefore(option, select.lastChild);
}
// add a change event listener to handle the language title
select.addEventListener('change', changeHeading);
// trigger a change event in order to display the selected language's title
select.dispatchEvent(new Event('change'));
function changeHeading(event) {
var language = arr.find(
(language) => language.id === parseInt(event.target.value)
);
document.getElementById('heading').innerHTML = language.title;
}
<!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>JavaScript Dropdown</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1 class="heading" id="heading"></h1>
<select class="drop" id="select"></select>
<script src="./main.js"></script>
</body>
</html>

Related

How to pass on dynamic delay to d3.interval

d3.interval takes two parameters, callback and delay,e.g.
d3.interval(callback, delay).
I was wondering if it is possible to pass on a dynamic delay for each interval.
For example, in the following, I am asking the interval to run at 1000ms delay. But is there a way I can ask d3.interval to run at 0ms, 1000ms, 2000ms, 3000ms respectively for interval# 1,2,3,4.
I tried like desiredDelay[counterF] but it did not work.
const masterSelection = d3.selectAll('[class^="text"]');
const node = masterSelection.nodes();
const len = node.length - 1;
let counterF = 0;
const del = 1000;
const desiredDelay = [0, 1000, 2000, 3000]
let ticker = d3.interval(
e => {
const element = masterSelection['_groups'][0][counterF];
const selection = d3.select(element).node();
console.log(selection);
counterF++;
(counterF > len) ? ticker.stop(): null
}, del
)
<!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>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<div class='text1'>one</div>
<div class='text2'>two</div>
<div class='text3'>three</div>
<div class='text4'>four</div>
</body>
<script type="text/javascript" src="prod.js"></script>
</html>
Short answer: you can't.
If you look at the source code you'll see that if the delay is not null...
if (delay == null) return t.restart(callback, delay, time), t;
...it will be coerced to a number using the unary plus operator:
t.restart = function(callback, delay, time) {
delay = +delay,
etc...
What you can do is creating your own interval function, which is out of the scope of this answer.
Adapted from this, the following works as desired and is to be used with d3.timeout.
const masterSelection = d3.selectAll('[class^="text"]');
const node = masterSelection.nodes();
const len = node.length - 1;
let counter = 0;
//const del = 1000;
const delay = [0, 1000, 2000, 3000];
function show() {
const element = masterSelection["_groups"][0][counter];
const selection = d3.select(element).node();
console.log(selection);
counter++;
if (counter > len) return
d3.timeout(show, delay[counter]);
}
show();
<!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>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<div class='text1'>one</div>
<div class='text2'>two</div>
<div class='text3'>three</div>
<div class='text4'>four</div>
</body>
<script type="text/javascript"></script>
</html>

I am not sure I can access the second html file using one js file, html element is showing as null when it is a button

I have 2 html files connected to one js file. When I try to access a html element in the second html file using js it doesn't work saying that is is null. I did
let elementname = document.getElementById("element") for a element in the second html page then
console.log(elementname) and it says it is null. When I do it for a element in the first html page it says HTMLButtonElement {}
Here is the html for the first Page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Not Quuuuiiiizzzz</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Not Quuuuiiiizzzz</h1>
<h2>Join a quiz</h2>
<!--Buttons -->
<div style="text-align: center;">
<button id="btnforquiz1" onclick="gotoquiz()"></button>
<button id="btnforquiz2" onclick="gotoquiz1()"></button>
<button id="btnforquiz3" onclick="gotoquiz2()"></button>
</div>
<h2 id="h2">Create a Quuuuiiiizzzz</h2>
<script src="script.js"></script>
</body>
</html>
For the second page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Not Quuuuiiiizzzz</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body onload="quizLoad()">
<h1 id="question">Hello</h1>
<button id="answer1"></button>
<button id="answer2"></button>
<button id="answer3"></button>
<button id="answer4"></button>
<script src="script.js"></script>
</body>
</html>
And Finally for the js file :
//setting global variables
let btn1 = document.getElementById("btnforquiz1") //getting button with id of btnforquiz1 repeat below
correct = 0
let btn2 = document.getElementById("btnforquiz2")
let btn3 = document.getElementById("btnforquiz3")
let question = document.getElementById("question")
let answer1 = document.getElementById("answer1")
let answer2 = document.getElementById("answer2")
let answer3 = document.getElementById("answer3")
let answer4 = document.getElementById("answer4")
quizNameRel = -1;
cosnole.log(question)
console.log(answer1)
//Quiz Data
Quiz_1 = {
"What is the capital of buffalo":["Idk", "Yes", "No",0],
"What is the smell of poop": ["Stinky"]
};
Quiz_2 = [
"What is wrong with you"
];
Quiz_3 = [
"What is wrong with you #2"
]
let quiz = {
name: ["History Test", "Math Practice", "ELA Practice"],
mappingtoans: [0,1,2],
QA: [Quiz_1, Quiz_2, Quiz_3]
}
//quiz data
//when body loades run showQuizzs function
document.body.onload = showQuizzs()
function showQuizzs() {
//loops throo the vals seeting the text for the btns
for (let i = 0; i < quiz.name.length; i++) {
btn1.textContent = quiz.name[i-2]
btn2.textContent = quiz.name[i-1]
btn3.textContent = quiz.name[i]
}
}
//leads to the showQuizzs
function gotoquiz() {
location.href = "quiz.html"
quizNameRel = quiz.name[0]//I was trying to create a relation so we could knoe which quiz they wnt to do
startQuiz()
}
function gotoquiz1() {
location.href = "quiz.html"
quizNameRel = quiz.name[1]
startQuiz()
}
function gotoquiz2() {
location.href = "quiz.html";
quizNameRel = quiz.name[2];
startQuiz();
}
function answerselect(elements){
whichone = Number(elements.id.slice(-2,-1))
if(Quiz_1[whichone]==Quiz_1[-1]){
correct+=1;
NextQuestion();
}else{
wrong+=1;
}
}
//gets the keys and puts it into an array
function getkeys(dictionary){
tempdict = [];
for(i in dictionary){
tempdict.push(i);
}
return tempdict;
}
function setQuestion() {
let tempdict = getkeys(Quiz_1)
console.log(tempdict, getkeys(Quiz_1));
//question.innerHTML = tempdict;
}
// startQuiz
function startQuiz() {
switch (quizNameRel){
case quiz.name[0]:
//case here
setQuestion()
break
case quiz.name[1]:
//case here
break
case quiz.name[2]:
//case here
break
}
}
//TO DO:
// Set the question
// Set the answer
// Check if correct button
This is happening because at a time you have rendered only one html file. For example if you render index1.html(first file) then your js will look for rendered element from first file only but here index2.html(second file) is not rendered so your js script is unable to find elements of that file that's the reason it shows null.
If you try to render now index2.html rather than index1.html then you will find now elements from index2.html are detected by js script but elements from index1.html are null now.

Mask original e-mail on registration page using Javascript

I need to setup a page that allows users to register using their e-mail but as a requirement the e-mail shouldn't be "visible" for human eyes, I guess there's got to be a better way to do it, but so far I came up with this option using JQuery:
I created a fake control that handles the masking and captures the text so that it can be assigned to a hidden field (so that the previously working code will keep working without changes).
var emailControl = $("#eMail");
var firstHalf = "";
var secondHalf = "";
var fullMail = "";
emailControl.keyup(function(e){
var control = e.currentTarget;
var currentText = $(control).val();
if (currentText.length == 0){
fullMail = '';
firstHalf = '';
secondHalf = '';
$(control).attr('type', 'password');
}
else{
var components = currentText.split("#");
var hiddenPart = "•".repeat(components[0].length);
detectChanges(currentText);
if (components.length == 2) {
secondHalf = '#' + components[1];
}
$(control).attr('type', 'text');
$(control).val(hiddenPart + secondHalf);
fullMail = firstHalf + secondHalf;
}
});
function detectChanges(originalText) {
var position = originalText.indexOf('#');
if (position == -1) {
position = originalText.length;
}
for (var i = 0; i < position; i++){
if (originalText[i] != "•"){
firstHalf = firstHalf.substring(0, i) + originalText[i] + firstHalf.substring(i+1);
}
}
}
I did manage to get it working here: https://codepen.io/icampana/pen/KbegKE
You could give the input tag type of password: type="password".
It may cause some janky things to happen with autofill.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form>
email: <input type="password" name="email">
</form>
</body>
</html>
You could also do something similar with CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
input {
-webkit-text-security: circle;
}
</style>
</head>
<body>
<form>
email: <input name="email">
</form>
</body>
</html>

referencing an object literal to set innerHTML in a span element javascript

I have a small data store of quotes like this:
let quotes = [{
quote: "Search others for their virtues, thyself for thy vices.",
source: "Benjamin Franklin",
citation: "Poor Richard\'s Almanac",
category: "ethics",
year: ''
}, {
quote: "He who has courage despises the future.",
source: "Napoleon Bonaparte",
citation: '',
category: "boldness",
year: ''
}
]
I am running a simple javascript function to change the html based on the data store with this:
const getRandomQuote = () => {
let quoteShownArr = [];
let quoteIndex = Math.floor((Math.random() * quotes.length) + 1);
for (let i = 0; i < quotes.length; i++) {
if (quoteIndex === i) {
document.getElementsByTagName("P")[0].innerHTML = quotes[i].quote;
document.getElementsByTagName("P")[1].innerHTML = quotes[i].source;
let citation = quotes[i].citation;
if(citation) {
console.log(citation);
document.getElementById("citation").innerHTML = quotes[i].citation;
}
document.getElementById("year").innerHTML = quotes[i].year;
}
}
}
getRandomQuote();
All the html elements are being updated except for my citation and year, which are span elements. I get the following error:
TypeError: "Cannot set property 'innerHTML' of null
at getRandomQuote" But the exact value consoles easily. How is this not changing the element??
Thanks.
HTML added:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Random Quotes</title>
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,400italic,700,700italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="container">
<div id="quote-box">
<p class="quote">You can do anything but not everything</p>
<p class="source">David Allen<span class="citation" id="citation">Making It All Work</span><span class="year" id="year">2009</span></p>
</div>
<button id="loadQuote">Show another quote</button>
</div>
<script src="js/script.js"></script>
</body>
</html>
in this line
document.getElementsByTagName("P")[1].innerHTML = quotes[i].source;
you set the inner html to the source text, removing all other html content e.G your spans, this is why they are null because they dont exist anymore

HTML dynamic page creation through menu with Javascript

i have a website application with a html page that contains a menu
when i press a button, parameters that show which action has to be perfomed added to url
ex ...html?action=show-charts
i want by reading those parameters with JS the body of the page be dynamically created for each instance
i thought of somwthing like that
html code:
<html>
<head>
<title>Bull Stock | Home</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
</head>
<body onload="updateBodyOnAction()">
<script>
function getUrlValue(VarSearch){
var SearchString = window.location.search.substring(1);
var VariableArray = SearchString.split('&');
for(var i = 0; i < VariableArray.length; i++){
var KeyValuePair = VariableArray[i].split('=');
if(KeyValuePair[0] === VarSearch){
return KeyValuePair[1];
}
}
}
</script>
<script>
function updateBodyOnAction() {
if(window.location.toString().indexOf("?") > -1){
var action = getUrlValue("action");
if(action.valueOf() === "show-charts"){
document.write("<h1 align=\"center\">CHARTS!</h1>"+
"<p align=\"center\">More Charts!</p>");
}
}
}
</script>
</body>
</html>
OR
with the method appendChild()
But i want to know if that's right and if there is a better way to do it or improvements of this one

Categories