addEventListner is not being assigned inside for loop (JS) - javascript

I am trying to create a to do list, for a long while now. I can input a task by typing it in the input and then pressing +. However, when I create the new button, I assign it a eventListener, yet the button does not work when it is pressed.
I thought that the problem was that the code for eventListener function was in a outside function and was being 'summoned' yet that was not the case because it still didn't work.
I am planning to make the close function along the lines of this.parentElement.remove() but I first need to be able to get a simple console.log() working for the button before anything else.
const input = document.getElementById("input")
const addBtn = document.getElementById("add")
addBtn.addEventListener('click', function(){addTask()})
const todoList = document.getElementById("todo-list")
let task = document.querySelectorAll('.task')
let closeBtn = document.querySelectorAll('.close')
let taskArray = []
function addTask () {
taskArray.push(input.value)
input.value = ""
renderTasks()
}
function renderTasks() {
let taskList = ""
for (let i = 0; i < taskArray.length; i++){
let newTask = document.createElement('li')
newTask.classList.add('task')
let newP = document.createElement('p')
newP.textContent = taskArray[i]
let newClose = document.createElement('button')
newClose.classList.add('close')
newClose.textContent = 'x'
newClose.addEventListener('click', function(){close()})
newTask.append(newP, newClose)
taskList += newTask.outerHTML
}
todoList.innerHTML = taskList
task = document.querySelectorAll('.task')
closeBtn = document.querySelectorAll('.close')
}
function check() {
console.log('check()')
}
function close() {
console.log('close()')
}
.task {
width: 200px;
height: 40px;
display: flex;
justify-content: space space-between;
align-items: center;
flex-direction: row;
}
.task p {
width: 70%;
}
.close {
display: inline-block;
width: 30px;
height: 30px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="/css/to-do.css">
<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>Todo</title>
</head>
<body>
<div class="control-wrp">
<input type="text" id="input" placeholder="type here">
<button id="add">+</button>
</div>
<div id="todo-wrp">
<ul id="todo-list">
</ul>
</div>
<script src="/javascript/to-do-list.js"></script>
</body>
</html>

Because you're adding dynamic elements, you can assign a delegate listener - where you place a listener on a static object, and then test that listener for the click you're looking for, like...
todoList.addEventListener('click', e => {
if (e.target.classList.contains('close')) close(e.target)
})
Then for your delete (close) function, you can use element.closest() to reference the container and just element.remove() it. closest() is better than parentElement as it protects you against certain future html structure changes
Event delegation: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_delegation
Element.closest: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
const input = document.getElementById("input")
const addBtn = document.getElementById("add")
addBtn.addEventListener('click', function() {
addTask()
})
const todoList = document.getElementById("todo-list")
todoList.addEventListener('click', e => {
if (e.target.classList.contains('close')) close(e.target)
})
let task = document.querySelectorAll('.task')
let closeBtn = document.querySelectorAll('.close')
let taskArray = []
function addTask() {
taskArray.push(input.value)
input.value = ""
renderTasks()
}
function renderTasks() {
let taskList = ""
for (let i = 0; i < taskArray.length; i++) {
let newTask = document.createElement('li')
newTask.classList.add('task')
let newP = document.createElement('p')
newP.textContent = taskArray[i]
let newClose = document.createElement('button')
newClose.classList.add('close')
newClose.textContent = 'x'
newTask.append(newP, newClose)
taskList += newTask.outerHTML
}
todoList.innerHTML = taskList
task = document.querySelectorAll('.task')
}
function check() {
console.log('check()')
}
function close(btn) {
btn.closest('.task').remove()
}
.task {
width: 200px;
height: 40px;
display: flex;
justify-content: space space-between;
align-items: center;
flex-direction: row;
}
.task p {
width: 70%;
}
.close {
display: inline-block;
width: 30px;
height: 30px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="/css/to-do.css">
<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>Todo</title>
</head>
<body>
<div class="control-wrp">
<input type="text" id="input" placeholder="type here">
<button id="add">+</button>
</div>
<div id="todo-wrp">
<ul id="todo-list">
</ul>
</div>
<script src="/javascript/to-do-list.js"></script>
</body>
</html>

Related

How could I make a function in JS that works like a Upgrade Button

So I want to make a clicker game and I am now at the part where I want to add a function to the 'upgrade click' button so that when I click it, it takes away 'x' amount of money but it makes my clicks generate 'x' more money
Here is my code:
"use strict";
let varible = 0
const button = document.getElementById('dollarButton');
button.addEventListener('click', myFunc);
function myFunc() {
varible++;
document.getElementById('score').innerHTML = "$" + varible
}
img
{
width:200px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button id="dollarButton" style="
border: none;
top: 45%;
left: 20%;
position: absolute;
cursor: pointer;
"><img src="https://www.pngfind.com/pngs/m/94-940164_button-images-png-button-background-image-green-transparent.png" /></button>
<h1 id="score">Time to Make Money!</h1>
<div id="updaCash" class="button red">
<span id="updaCash_text" class="color-white">Upgrade click</span>
</div>
<script src="script.js"></script>
</body>
</html>
You'd want to add a event listener to updaCash that fires whenever it's clicked. I'd also suggest adding a variable that tracks how much money is added per click. For example:
script.js
"use strict";
function myFunc() {
varible += amountToAdd;
document.getElementById('score').innerHTML = "$" + varible
}
function upgradeClick() {
amountToAdd += 1; // 1 could be any other number you'd like
}
let varible = 0;
const amountToAdd = 1;
const button = document.getElementById('dollarButton');
const upgradeButton = document.getElementById("updaCash");
button.addEventListener('click', myFunc);
upgradeButton.addEventListener("click", upgradeClick);
Hope this helps! And good luck on your clicker game :D
You need to change your js code.
So your final Js code look like:
"use strict";
function myFunc() {
varible += amountToAdd;
document.getElementById('score').innerHTML = "$" + varible
}
function upgradeClick() {
amountToAdd += 1;
}
let varible = 0;
const amountToAdd = 1;
const button = document.getElementById('dollarButton');
const upgradeButton = document.getElementById("updaCash");
button.addEventListener('click', myFunc);
upgradeButton.addEventListener("click", upgradeClick);
Similarly Your HTML code looks like:
<button id="dollarButton">
<img src="https://fastly.picsum.photos/id/2/200/300.jpg?hmac=HiDjvfge5yCzj935PIMj1qOf4KtvrfqWX3j4z1huDaU" /></button>
<h1 id="score">Time to Make Money!</h1>
<div id="updaCash" class="button red">
<span id="updaCash_text" class="color-white">Upgrade click</span>
</div>
</button>
And Your CSS code :
#dollarButton{
border: none;
top: 45%;
left: 45%;
position: absolute;
cursor: pointer;
}
Here you have to use another variable to keep track of the amount. So when you click the button x amount is added and next time you click x more amount is added.
"use strict";
let varible = 0
let amount =1
const button = document.getElementById('dollarButton');
button.addEventListener('click', myFunc);
function myFunc() {
varible+=amount;
amount+=1 // replace 1 with x (value you want)
document.getElementById('score').innerHTML = "$" + varible
}
img
{
width:200px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button id="dollarButton" style="
border: none;
top: 45%;
left: 20%;
position: absolute;
cursor: pointer;
"><img src="https://www.pngfind.com/pngs/m/94-940164_button-images-png-button-background-image-green-transparent.png"/></button>
<h1 id="score">Time to Make Money!</h1>
<div id="updaCash" class="button red">
<span id="updaCash_text" class="color-white">Upgrade click</span>
</div>
<script src="script.js"></script>
</body>
</html>

I want a file value or name when I upload a file in html javascript?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<style type="text/css">
#filee{
visibility: hidden;
}
</style>
</head>
<body>
<input type="file" name="" id="filee">
<button onclick= "ftn()" id="btn">Choose a File</button>
<span id="filename"></span>
<script type="text/javascript">
let file = document.getElementById('filee');
let btn = document.getElementById("btn");
let filename = document.getElementById("filename");
function ftn(){
file.click();
let value = file.value;
filename.innerText = value;
}
</script>
</body>
</html>
This is my code. I'm getting value when i clicked button 2nd time. I want a value in span tag of my file when i click on button and open it. This giving value when i clicked again a button and show me previous value of file. Thanks if you get my point
You'll want to know the name of the file whenever you've uploaded it to the browser. That means that you have to listen for the change event on the file input.
let file = document.getElementById('filee');
let btn = document.getElementById("btn");
let filename = document.getElementById("filename");
file.addEventListener('change', event => {
const [file] = event.target.files
filename.innerText = file.name;
});
btn.addEventListener('click', () => {
file.click();
});
#filee {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
<input type="file" name="" id="filee">
<button type="button" id="btn">Choose a File</button>
<span id="filename"></span>

open links in iframe one by one when press button

i've a array of three links for a button which i'm using in footer and when i press the button again and again , array will work one by one good ..and every time it shows a link when press the button. That is good.
but i want , when i click on button that "link" should open in "iframe" ... i used iframe code to pass them src= button id but not working.. please below code and help..
.
my button code with array
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: red;
color: white;
text-align: center;
}
</style>
<script>
let link = new Array()
link[0] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL3+8QE&distance=20"
link[1] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL5+3NG&distance=20"
link[2] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL4+3NS&distance=20"
let intlinkIndex = 0;
function writeLink() {
if (intlinkIndex >= link.length) {
let btn = document.getElementById('btn');
btn.style.display = 'none';
mylink.style.display = 'none';
}
document.getElementById('mylink').innerHTML = '' + link[intlinkIndex] + '';
intlinkIndex++;
}
</script>
</head>
<body>
<div class="footer">
<button id="btn" onclick="writeLink();">Click Me</button>
<div id="mylink"></div>
<br>
<iframe id="iframe" src="mylink" width="100%" height="400"></iframe>
</div>
</body>
</html>
You can get it by specifying iframe's name in target when generating link html.
So add a name property in your iframe like following:
<iframe id="iframe" name="iframe" src="mylink" width="100%" height="400"></iframe>
Then add a target property.
document.getElementById('mylink').innerHTML = '' + link[intlinkIndex] + '';
function writeLink() {
if (intlinkIndex >= link.length) {
let btn = document.getElementById('btn');
btn.style.display = 'none';
mylink.style.display = 'none';
}
document.getElementById('mylink').innerHTML = '' + link[intlinkIndex] + '';
document.getElementById('iframe').src = link[intlinkIndex];
intlinkIndex++;
}
Full source code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: red;
color: white;
text-align: center;
}
</style>
<script>
let link = new Array()
link[0] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL3+8QE&distance=20"
link[1] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL5+3NG&distance=20"
link[2] = "https://www.clc-uk.org.uk/cms/cms.jsp?menu_id=26131&postcode=AL4+3NS&distance=20"
let intlinkIndex = 0;
function writeLink() {
if (intlinkIndex >= link.length) {
let btn = document.getElementById('btn');
btn.style.display = 'none';
mylink.style.display = 'none';
}
document.getElementById('mylink').innerHTML = '' + link[intlinkIndex] + '';
document.getElementById('iframe').src = link[intlinkIndex];
intlinkIndex++;
}
</script>
</head>
<body>
<div class="footer">
<button id="btn" onclick="writeLink();">Click Me</button>
<div id="mylink"></div>
<br>
<iframe id="iframe" src="mylink" width="100%" height="400"></iframe>
</div>
</body>
</html>

Add enterkeypress function for adding list in javascript and organize the list style properly in todo

I want to add enterfunction into Javascript for my TODO list project,in which I can press the enter key and the item should be added, now I am able to add list through add button only.
Secondly, I want to organize The List properly for TODO list by giving some style. rightnow it doesn't looks good.
Rightnow my TODOLIST project looks like this https://i.stack.imgur.com/V1j5z.png
var add = document.getElementById('add');
var removeall = document.getElementById('removeall');
var list = document.getElementById('list');
//remove all button
removeall.onclick= function(){
list.innerHTML= '';
}
//adding a list element
add.onclick = function(){
addlis(list);
document.getElementById('userinput').value= '';
document.getElementById('userinput').focus();
}
function addlis(targetUl){
var inputText = document.getElementById('userinput').value;
var li = document.createElement('li');
var textNode= document.createTextNode(inputText + ' ');
var removeButton= document.createElement('button');
if(inputText !== ''){
removeButton.className= 'btn btn-xs btn-danger';
removeButton.innerHTML= '×';
removeButton.setAttribute('onclick','removeMe(this)');
li.appendChild(textNode); //onebelowanother
li.appendChild(removeButton);
targetUl.appendChild(li);
} else{
alert("Please enter a TODO");
}
}
function removeMe(item){
var p = item.parentElement;
p.parentElement.removeChild(p);
}
body{
font-family: 'EB Garamond', serif;
padding: 0;
margin: 0;
background-color: beige;
}
h1{
margin: 40px;
}
#userinput{
width: 350px;
height: 35px;
display: inline-block;
}
.btn{
margin: 20px 5px;
}
.form-control{
margin: 0 auto;
}
ul{
list-style: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="css/TodoStyle.css">
<link href="https://fonts.googleapis.com/css?family=EB+Garamond&display=swap" rel="stylesheet">
<title>My Online TODO List App</title>
</head>
<body>
<div class="container-fluid text-center">
<h1>My First working TODO</h1>
<input type="text" id="userinput" class="form-control" placeholder="what you need to do" onkeydown="return searchKeyPress(event);">
<button class="btn btn-success" id="add">Add a TODO</button>
<button class="btn btn-danger" id="removeall">REMOVE ALL TODO</button>
<ul id="list">
<li class="list"></li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="js/Todo.js"></script>
</body>
</html>
Just wrap all the inputs and buttons inside a form tag like this:
<form id="...">
<input type="text" id="userinput" class="form-control" placeholder="what you need to do" onkeydown="return searchKeyPress(event);">
<button type="submit" class="btn btn-success" id="add">Add a TODO</button>
</form>
and replace this:
add.onclick = function(){...})
with
form = document.getElementBy...
form.addEventListener('submit', function() {...})
Also try to avoid writing add.onclick and use addEventListener. That way you can have multiple listeners, remove them easily, and overall have more control.
Use event listener for key press on your input (13 is the enter key):
var input = document.getElementById("userinput");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
searchKeyPress(event);
}
});

Toggling the value displayed in a DIV depending on which DIV the click is performed

I have 4 (or more) DIV elements on which I want to set this behavior:
In the beginning, all DIVs display A
I click on a random DIV. It must display B. Other DIVs must keep displaying A
If the consecutive click is performed on the same DIV, this later one must display back A. Others must keep displaying A.
If the consecutive click is performed on a different DIV, this later one must display B. All other DIVs must display A
This is what I am working on. I have had hard time to do anything useful.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
.divElt {
margin-left: 20%;
width: 80px;
height: 40px;
background-color: blue;
color: white;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<script>
var data = 'B';
function funct() {
var elts = document.getElementsByClassName('divElt')
for(var i = 0; i < elts.length; i++) {
elts[i].innerHTML = data
}
}
</script>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
</body>
</html>
Please help me to resolve this only in JavaScript (no jQuery or other libraries). Thank you a lot in advance.
var letterA = "A";
var letterB = 'B';
//Init with all "A"
var elts = document.getElementsByClassName('divElt');
for (var i = 0; i < elts.length; i++) {
elts[i].innerHTML = letterA;
}
function funct(item) {
for (var i = 0; i < elts.length; i++) {
if (elts[i] !== item)
elts[i].innerHTML = letterA;
else
elts[i].innerHTML = elts[i].innerHTML === letterA ? letterB : letterA;
}
}
.divElt {
margin-left: 20%;
width: 80px;
height: 40px;
background-color: blue;
color: white;
font-weight: bold;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<script>
</script>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
</body>
</html>
To uniquely identify the div which was clicked, pass this to the called function like so onclick=func(this)
Then inside your function receive it as a parameter
function func(elem) {
var elts = document.getElementsByClassName('divElt');
for(var i = 0; i < elts.length; i++) {
elts[i].innerHTML = 'A';
}
elem.innerHTML = elem.innerHTML === 'B' ? 'A' : 'B';
}

Categories