parameter is coming out undefined - javascript

I am in the process of building a hangman game. In my checkLetter function is where i am going to write code to check if a letter matches a chosen word. However I have noticed that when i passed in letter to onclick for function checkLetter, the console log will come out undefined but it will also display collection of html tags from the button that is pressed. In the function checkLetter i passed in pickLetter as a parameter. This is where buttons work but it also comes out undefined. I am very certain that I wrote this correctly but i know something is missing. Any help? I hope i made myself clear.
document.body.onload = createButtons;
//keyboard added dynamically
function createButtons() {
const buttons = alphabet.map(letter =>
`<button id = "${letter}"
class="btn btn-primary letterKey"
button type="button"
value="${letter}"
onclick = "checkLetter(${letter})"
>
${letter}
</button>`).join('');
keyboardBtn.innerHTML = buttons;
//prints letters to answer input/screen
Array.from(document.getElementsByClassName("letterKey"))
.forEach((e) =>
e.addEventListener("click", () => placeLetters.innerHTML += e.value))
}
//check letter of chosen word, if its there or not
function checkLetter(pickLetter) {
console.log(pickLetter)
}
checkLetter();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<title>Hangman 2021</title>
</head>
<body>
<!--header-->
<header class="container-fluid bg-success text-dark">
<div>
<span>
<h1 class="text-center">Hang that man</h1>
</span>
</div>
</header>
<div class="container">
<br>
<h3>Please choose a letter on your keyboard to reaveal the secret word</h3>
<br>
<!--each letter will display after all lives are gone-->
<div id="keyboard"></div>
<br>
<br>
<!--choices will be inserted here-->
<div id="answer-input">
<p id="letter-input">_ _ _ _ _ _ _ _ _ _ _ </p>
</div>
<!--number of lives will be tracked here-->
<p id="lives">You have 8 lives left</p>
<!--everytime a guess is wrong, a limb is added to animation-->
<section class="animation">
<div class="justify-content-center">
<canvas id="gallows" width="300" height="150" style="border:1px solid #d3d3d3"></canvas>
</div>
<button id="reset">Play Again</button>
</section>
<br>
</div>
<!--footer-->
<footer class="container-fluid bg-success text-dark">
<div class="justify-content-center">Hang that man © 2021</div>
<div class="social justify-content-center">
<i class="fab fa-linkedin"></i>
|
<i class="fab fa-github"></i>
</div>
<div class="github">
<a>Andres Ramirez</a>
</div>
</footer>
<script type="text/javascript"src="index.js" defer></script>
</body>
</html>

have you tried using :
Array.from(document.getElementsByClassName("letterKey"))
.forEach((e) =>
e.addEventListener("click", () => placeLetters.innerText+= e.value))
(note that innerHtml returns everything from html) you could try:
placeLetters.textContent
placeLetters.innerText
placeLetters.value

I created an example with comments. You can use it to see how to handle the clicks. I would advise to use event delegation to handle click events instead of 26 separate handlers. See this blog for more info. I added comments to the code below so it's pretty clear but let me know if you have any questions. The game obviously isn't 100% finished, but should be enough so you can take it from there.
//Your HTML elements that will be used for the game UI
const btnContainerEl = document.querySelector("#btn-container");
const guessTrackerEl = document.querySelector("#guess-tracker");
const winningWordEl = document.querySelector("#winning-word");
//Some const variables to avoid magic numbers in the code
const CHAR_CODE_a = 97;
const STRIKES_TIL_HANGED = 5;
//A variable to keep track of the remaining letters the player needs to win
let lettersNeededToWin;
//A variable to keep track of unsuccessful guesses
let strikes = 0;
initGame();
function initGame() {
getWinningWord();
createLetterButtons();
}
function getWinningWord() {
//Get the winning word from a prompt and create an array of it's letters
lettersNeededToWin = window.prompt("Enter winning word").toLowerCase().split('').sort();
}
function createLetterButtons() {
//Loop 26 times to create a button for each letter in the English alphabet
for (let i = 0; i < 26; i++) {
const char = String.fromCharCode(CHAR_CODE_a + i);
const btnText = document.createTextNode(char);
const buttonEl = document.createElement("BUTTON");
buttonEl.appendChild(btnText);
//Append the button the UI
btnContainerEl.appendChild(buttonEl);
}
//Add a click event to the parent container instead of each individual button.
btnContainerEl.addEventListener('click', handleLetterButtonClick);
//1 event handler is more efficient than 26 seperate handlers.
}
function handleLetterButtonClick(e) {
if (e.target.tagName != "BUTTON") {
return;
}
e.target.disabled = true;
updateGuessTracker(e.target.textContent);
if (lettersNeededToWin.includes(e.target.textContent)) {
while (lettersNeededToWin.includes(e.target.textContent)) {
//Remove these letters from the array (in-place operation)
lettersNeededToWin.splice(lettersNeededToWin.indexOf(e.target.textContent), 1);
}
} else {
//Add another strike since players guess was incorrect
strikes++;
}
//Check the number of letters left and number of strikes to determine win/lose outcome
if (lettersNeededToWin.length == 0) {
console.log("YOU WIN!");
} else if (strikes == STRIKES_TIL_HANGED) {
console.log("YOU LOSE!");
}
}
function updateGuessTracker(guessLetter) {
guessTrackerEl.innerHTML += `<font color="${lettersNeededToWin.includes(guessLetter) ? 'green' : 'red'}">${guessLetter}</font> `;
}
<div id="winning-word">Winning word:</div>
<br/>
<div id="btn-container"></div>
<div id="guess-tracker">Guessed letters:</div>

Related

I am trying to make a todo list in javascript but the HTML doesn't show it [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm trying to code a todo list in javascript, but somehow it doesn't work.
this is my JavaScript and HTML:
let todos = []
function createTodo() {
let newTodo = {
text: '',
checked: 0
}
newTodo['text'] = prompt('Item description')
todos.push(newTodo)
}
for (i in todos) {
let listItem = document.createElement('li')
let itemText = document.createTextNode(i['text'])
console.log('itemText: ' + itemText)
listItem.appendChild(itemText)
console.log('listItem: ' + listItem)
document.getElementById('todo-list').appendChild(listItem)
}
<!DOCTYPE html>
<html>
<head>
<title>TODO App</title>
<link rel="stylesheet" type="text/css" href="./styles.css" />
</head>
<body>
<div class="container center">
<h1 class="center title">My TODO App</h1>
<div class="flow-right controls">
<span>Item count: <span id="item-count">0</span></span>
<span>Unchecked count: <span id="unchecked-count">0</span></span>
</div>
<button class="button center" onClick="createTodo();">New TODO</button>
<ul id="todo-list" class="todo-list">
</ul>
</div>
<script src="./script.js"></script>
</body>
</html>
When I click the todo button it prompts me for text, and when i type in the console it does show that it's been pushed; but when iterated with a for loop it shows 'undefined' in the console, plus it doesn't even show up in the HTML. Please help me.
As I can see in your code, there is nowhere to add created elements to HTML.
And when it comes to open prompt, you should get value from the input.
This is how to get input value and reflects it to the HTML
let todos = []
function createTodo() {
let newTodo = {
text: '',
checked: 0
}
newTodo['text'] = prompt('Item description')
if( newTodo.text != null ) {
todos.push(newTodo)
reflectToHtml(newTodo)
}
}
function reflectToHtml(i) {
let listItem = document.createElement('li')
let itemText = document.createTextNode(i['text'])
listItem.appendChild(itemText)
document.getElementById('todo-list').appendChild(listItem)
document.getElementById('item-count').innerText = todos.length
}
Maybe try:
let todos = []
for (i in todos) {
let listItem = document.createElement('li')
let itemText = document.createTextNode(i.text)
alert('itemText: ' + itemText)
listItem.appendChild(itemText)
alert('listItem: ' + listItem)
document.getElementById('todo-list').appendChild(listItem)
}
function createTodo() {
let newTodo = {
text: '',
checked: 0
}
var addTodo = prompt('Item description');
newTodo.text = addTodo;
todos.push(newTodo);
let listItem = document.createElement('li')
let itemText = document.createTextNode(newTodo.text)
alert("Added new todo. Todo:\n" + addTodo);
listItem.appendChild(itemText)
document.getElementById('todo-list').appendChild(listItem)
alert("Succesfuly created todo.");
}
<!DOCTYPE html>
<html>
<head>
<title>TODO App</title>
<link rel="stylesheet" type="text/css" href="./styles.css" />
</head>
<body>
<div class="container center">
<h1 class="center title">My TODO App</h1>
<div class="flow-right controls">
<span>Item count: <span id="item-count">0</span></span>
<span>Unchecked count: <span id="unchecked-count">0</span></span>
</div>
<button class="button center" onClick="createTodo();">New TODO</button>
<ul id="todo-list" class="todo-list">
</ul>
</div>
<script src="./script.js"></script>
</body>
</html>
The problem was that when your program first ran, it appended an empty list to the div. Then, you appended the item to the list of todos. The loop won't run again. I changed this code slightly. NOW, it adds it to the list, but its main functionality is that it directly appends the item to the list. This solution should work. There are other ways, but this one is the most convenient, personally.

Why is text in between bold tags not rendered bold?

I am building a web tool for authors that follows a format we need for our backend. I didn't like a number of pre-made solutions for rich text editors as they were having way more features than I would need so I decided to parse my text through a function to detect bold using ** in the text.
I came across a regex solution here and when I used it, it detected the bold text and substituted * for <b> but displayed the tags instead of making the text between <b> and </b> bold.
I am new to HTML, CSS and JS so probably this is a simple error, but I couldn't find out how to deal with it myself...
// Tracks number of current textareas i.e. paragraphs
var element_counter = 0;
// Add Paragraph on button press
document.getElementById("addParagraph").addEventListener("click", function() {
var textarea = document.createElement("textarea");
var text = "Here goes your new paragraph.";
var node = document.createTextNode(text);
textarea.setAttribute("id", element_counter);
//textarea.setAttribute("class", "flow-text");
//textarea.setAttribute("oninput", "this.style.height = '';this.style.height = this.scrollHeight + 'px'");
textarea.append(node);
var section = document.getElementById("editor");
section.appendChild(textarea);
element_counter++;
reloadPreview();
});
// Add Image on button press
document.getElementById("addImage").addEventListener("click", function() {
var image = document.createElement("input");
image.setAttribute("type", "file");
image.setAttribute("id", element_counter);
image.setAttribute("accept", "image/*");
image.setAttribute("class", "file-field input-field");
var section = document.getElementById("editor");
section.appendChild(image);
element_counter++;
});
// Remove paragraph with confirmation step on button press
var confirm = false;
document.getElementById("removeLastItem").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirm === false) {
confirm = true;
document.getElementById("removeLastItem").innerHTML = "Confirm";
} else {
document.getElementById("removeLastItem").innerHTML = "Remove last item";
var element = document.getElementById(element_counter-1);
element.parentNode.removeChild(element);
confirm = false;
element_counter--;
reloadPreview();
}
}
});
// Remove all with confirmation step on button press
var confirmRemoveAll = false;
document.getElementById("removeAll").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirmRemoveAll === false) {
confirmRemoveAll = true;
document.getElementById("removeAll").innerHTML = "Confirm";
} else {
document.getElementById("removeAll").innerHTML = "Remove all";
var element = document.getElementById("editor").innerHTML = ""
confirmRemoveAll = false;
element_counter = 0;
reloadPreview();
}
}
});
// Preview on button press
document.getElementById("previewButton").addEventListener("click", reloadPreview);
// Preview current document status
function reloadPreview() {
// Clear previous preview
document.getElementById("preview").innerHTML = "";
// Add elements iteratively
var section = document.getElementById("preview");
const id = "preview";
for (var counter = 0; counter < element_counter; counter++) {
var type = document.getElementById(counter).nodeName;
// If text element
if (type === "TEXTAREA") {
var paragraph = document.createElement("p");
var text = document.getElementById(counter).value;
var richtext = boldText(text);
paragraph.setAttribute("id", id + counter);
paragraph.setAttribute("class", "flow-text");
paragraph.innerHTML = richtext;
section.appendChild(paragraph);
}
// If image element
if (type === "INPUT") {
// This weird structure allows to render item by item into preview and not mix up the order as onload is otherwise too slow
(function() {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
reader.onload = function(e) {
image.setAttribute("src", e.target.result);
}
reader.readAsDataURL(file);
}())
}
}
}
function boldText(text){
var bold = /\*\*(\S(.*?\S)?)\*\*/gm;
var richtext = text.replace(bold, '<b>$1</b>');
return richtext;
}
<!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>Climate Science</title>
<!--Used to unify web page appearance and this preview appearance-->
<link type="text/css" href="/css/materialize.css" rel="stylesheet">
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<link type="text/css" href="/css/mystyles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap" rel="stylesheet">
<script href="text/javascript" src="/js/materialize.js"></script>
<link rel="manifest" href="/manifest.json">
<!-- IOS Support -->
<link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
<link rel="apple-touch-icon" href="/img/icons/icon-152x152.png">
<meta name="apple-mobile-web-app-status-bar" content="#5368ff">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="#5368ff">
</head>
<body class="grey lighten-5">
<header>
<!-- top nav -->
<div class="navbar-fixed">
<nav class="z-depth-2">
<div class="nav-wrapper">
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Log out</li> <!--TODO needed?-->
</ul>
</div>
</nav>
</div>
</header>
<div class="container">
<h3>Editor Area</h3>
<p><b>Linebreaks</b> within paragraphs are currently <b>ignored</b> to follow our internal database format.</p> <!--TODO check if accurate, \n possible integratable?-->
<!--
<h6>Safety switch</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>You can only remove paragraphs while the switch is deactivated!</p>
<h6>Auto-preview</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>The preview will load automatically while you edit your text</p>
<br>
-->
<button id="addParagraph" class="waves-effect waves-light btn">Add new paragraph</button>
<button id="addImage" class="waves-effect waves-light btn">Add new image</button>
<button id="removeLastItem" class="waves-effect waves-light btn">Remove last item</button>
<button id="removeAll" class="waves-effect waves-light btn">Remove all</button>
<div id="editor">
<!-- Here go all the content the author creates-->
</div>
<button id="previewButton" class="waves-effect waves-light btn">Update Preview</button>
<h3>Preview</h3>
<div id="preview">
<!-- Here will be the preview elements when clicking the button -->
<!--
<form action="#">
<p class="flow-text">What changes do you think we're already experiencing? Tap as many that apply</p>
<p>
<label>
<input type="checkbox" />
<span>Raising Sea Levels</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Fewer Heat Waves</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Worse Droughts</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Hotter heat waves</span>
</label>
</p>
<button class="btn waves-effect waves-light btn-large" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</form>
-->
</div>
</div>
<script href="text/javascript" src="js/preview.js"></script>
<script href="text/javascript" src="js/ui.js"></script>
</body>
</html>
Hi so perhaps use innerHTML to insert HTML into the tag body? So instead of paragraph.append:
paragraph.innerHTML = richtext;

How to remove list items from a parent with vanilla JS using the remove method?

Warning: my javascript code looks messy. I still have to modularize it a bit more
I am trying to remove list items from a parent node, which were once added by the addPhraseToDisplay function. The code that I used for this is commented out under buttonElement.innerHTML="Start Over", so zoom to that area of the code to save time.
let missed=0;
const qwertyID=document.getElementById('qwerty');
const phraseID=document.getElementById('phrase');
const buttonElement=document.getElementsByClassName("btn__reset")[0];
const overLay=document.getElementById('overlay');
const phraseArray=["Hey man","This is weird","I am bored","That is nice","That is cool"];
const ul=document.getElementsByTagName('UL')[0];
const heading=document.querySelector('.title');
//picks random phrase from phraseArray,breaks phrase into character array
//returns arr---character array to be displayed
function getRandomPhraseAsArray(array) {
index = Math.floor((Math.random() * array.length))
let str=array[index];
let arr=[...str];
console.log(arr);
return arr;
}
//appends each character as list items in ul
//takes arr in parameter
function addPhraseToDisplay(characterArray) {
for (let i=0; i<characterArray.length; i+=1) {
let char=characterArray[i];
listItem=document.createElement('LI');
listItem.textContent=char;
if (char!==" ") { //make code cleaner
listItem.classList.add("letter");
}
ul.appendChild(listItem);
}
}
//takes button as parameter and checks its letter
//checks letter class name in list, checks for match, and adds class show
function checkLetter(buttonKey) {
buttonText=buttonKey.textContent;
lettersList=document.getElementsByClassName('letter');
let match=null;
for (let i=0;i<lettersList.length;i+=1) {
if (lettersList[i].textContent.toLowerCase()===buttonText) {
lettersList[i].classList.add("show");
match=true;
}
}
return match;
}
//compares number of letter classes with show classes and checks missed variable
function checkWin () {
letterClassLength=document.getElementsByClassName('letter').length;
showClassLength=document.getElementsByClassName('show').length;
if (letterClassLength===showClassLength) {
overLay.classList.add("win");
heading.innerHTML="You win!";
overLay.style.display="flex";
buttons=document.querySelectorAll('.keyrow button'); //repeated code
for (let i=0; i<buttons.length;i+=1) {
buttons[i].disabled=false;
}
} else if (missed>=5) {
overLay.classList.add("lose");
heading.innerHTML="You lose!";
overLay.style.display="flex";
buttons=document.querySelectorAll('.keyrow button'); //repeated code
for (let i=0; i<buttons.length;i+=1) {
buttons[i].disabled=false;
}
}
buttonElement.innerHTML="Start Over";
buttonElement.addEventListener('click', ()=> {
overLay.style.display="none";
chosen=document.getElementsByClassName('chosen');
show=document.getElementsByClassName('show');
// list_items=document.querySelectorAll('letter');
for (let i=0; i<chosen.length;i+=1) {
chosen[i].classList.remove('chosen');
}
for (let i=0; i<show.length;i+=1) {
show[i].classList.remove('show');
}
// for (let i=0; i<list_items.length;i+=1) {
// ul.remove(list_items[i]);
// }
phraseDisplayed=getRandomPhraseAsArray(phraseArray);
addPhraseToDisplay(phraseDisplayed);
});
}
//listener event to button to hide overlay
buttonElement.addEventListener('click', ()=> {
overLay.style.display="none";
});
//stores arr (character array) from function into variable
//inputs variable (character array) into new function
let phraseDisplayed=getRandomPhraseAsArray(phraseArray);
addPhraseToDisplay(phraseDisplayed);
//adds class chosen to key and disables it
//if button pressed did not match, remove one try from scoreboard and update missed
qwertyID.addEventListener('click', (e)=>{
let button=e.target;
button.classList.add("chosen");
button.disabled="true";
let letterFound=checkLetter(button);
ol=document.getElementsByTagName('OL')[0];
tries=document.getElementsByClassName('tries')[0];
if (letterFound==null) {
ol.removeChild(tries);
missed+=1;
}
checkWin();
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Wheel of Success!</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/styles.css" rel="stylesheet">
</head>
<body>
<div class="main-container">
<div id="overlay" class="start">
<h2 class="title">Wheel of Success</h2>
<a class="btn__reset">Start Game</a>
</div>
<div id="banner" class="section">
<h2 class="header">Wheel of Success</h2>
</div>
<div id="phrase" class="section">
<ul></ul>
</div>
<div id="qwerty" class="section">
<div class="keyrow">
<button>q</button><button>w</button><button>e</button><button>r</button><button>t</button><button>y</button><button>u</button><button>i</button><button>o</button><button>p</button>
</div>
<div class="keyrow">
<button>a</button><button>s</button><button>d</button><button>f</button><button>g</button><button>h</button><button>j</button><button>k</button><button>l</button>
</div>
<div class="keyrow">
<button>z</button><button>x</button><button>c</button><button>v</button><button>b</button><button>n</button><button>m</button>
</div>
</div>
<div id="scoreboard" class="section">
<ol>
<li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
<li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
<li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
<li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
<li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
</ol>
</div>
</div>
</body>
<script src="app.js"></script>
</html>
I tried using the remove method, but this did not work. Instead, it added more list items then necessary when the game restarted. Did I not use it properly? Should I have done something different?
I know theres an easier way to restart the program, but I am supposed to manually restart relevant variables as per instructions for this project, so I can't use short cut methods to reload the page.

Why second button is not doing anything here?

I got a todo app in JavaScript which can add, delete entries against their functions. But once its clicks edit button only the first item is responding but other fails to do anything..
How to make it responsive and do the edit here.
Here is my code:
// Define UI Vars
const form = document.querySelector('#task-form');
const taskList = document.querySelector('.collection');
const clearBtn = document.querySelector('.clear-tasks');
const filter = document.querySelector('#filter');
const taskInput = document.querySelector('#task');
const editList = null;
// Load all event listeners
loadEventListeners();
// Load all event listeners
function loadEventListeners() {
// Add task event
form.addEventListener('submit', addTask);
// Remove task event
taskList.addEventListener('click', removeTask);
//edit task
//
// Clear task event
clearBtn.addEventListener('click', clearTasks);
// Filter tasks event
filter.addEventListener('keyup', filterTasks);
}
// Add Task
function addTask(e) {
if(taskInput.value === '') {
alert('Add a task');
}
// Create li element
const li = document.createElement('li');
// Add class
li.className = 'collection-item';
// Create text node and append to li
li.appendChild(document.createTextNode(taskInput.value));
// Create new link element
const link = document.createElement('a');
// Add class
link.className = 'delete-item secondary-content';
// Add icon html
link.innerHTML = '<i class="fa fa-remove"></i>';
// Append the link to li
li.appendChild(link);
// Append li to ul
taskList.appendChild(li);
const editButton=document.createElement("button");//edit button
editButton.className="editbtn";
editButton.innerText="Edit";//innerText encodes special characters, HTML does not.
li.appendChild(editButton);
taskList.appendChild(editButton);
const editList = document.querySelector('.editbtn');
editList.addEventListener('click',editTask)
// Clear input
taskInput.value = '';
e.preventDefault();
}
// Remove Task
function removeTask(e) {
if(e.target.parentElement.classList.contains('delete-item')) {
if(confirm('Are You Sure?')) {
e.target.parentElement.parentElement.remove();
}
}
}
// Clear Tasks
function clearTasks() {
// taskList.innerHTML = '';
// Faster
while(taskList.firstChild) {
taskList.removeChild(taskList.firstChild);
}
// https://jsperf.com/innerhtml-vs-removechild
}
// Filter Tasks
function filterTasks(e) {
const text = e.target.value.toLowerCase();
document.querySelectorAll('.collection-item').forEach(function(task){
const item = task.firstChild.textContent;
if(item.toLowerCase().indexOf(text) != -1){
task.style.display = 'block';
} else {
task.style.display = 'none';
}
});
}
function editTask (e) {
console.log('clicked')
}
<!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">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<title>Task List</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col s12">
<div id="main" class="card">
<div class="card-content">
<span class="card-title">Task List</span>
<div class="row">
<form id="task-form">
<div class="input-field col s12">
<input type="text" name="task" id="task">
<label for="task">New Task</label>
</div>
<input type="submit" value="Add Task" class="btn">
</form>
</div>
</div>
<div class="card-action">
<h5 id="task-title">Tasks</h5>
<div class="input-field col s12">
<input type="text" name="filter" id="filter">
<label for="filter">Filter Tasks</label>
</div>
<ul class="collection"></ul>
Clear Tasks
</div>
</div>
</div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.js"
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="app.js"></script>
</body>
</html>
Thanks for reading my question
Regards
because const editList = document.querySelector('.editbtn'); is selecting the first button it finds and adds a click. It is NOT selecting the button you just added. So that first element is than firing that function multiple times since you keep adding more and more event listeners to it.
You already have the reference to the button, so there is no need to look it up.
editButton.addEventListener('click', editTask)
document.querySelector() returns the first element matched.Every time you will call this querySelector() it will return the first edit button. Directly addEventListener to the editButton instead of calling it from querySelector()
editButton.addEventListener('click',editTask)

Building calculator - Not getting it to work

I'm building a calculator, and while it's starting to work, I'm kind of stuck. I've pasted the HTML and the JS down here.
I've been trying to figure out what went wrong, and I think it's because of the functions calling each other and not properly... "closing/ending". I've been trying to see what went wrong with adding console.logs. I'll break it down here:
I press "on" and function listenFirst gets run.
listenFirst has an eventListener and waits for the user to click a number (firstNumber). As soon as a number is clicked, waitforOperator is run (which now has the firstNumberas an attribute. Now,
waitforOperator waits for a click on the plus sign, and as soon as the user clicks on the plus sign, listenSecondgets run. Now this is where it
goes wrong: as soon as I click the second number, waitforOperatorgets run again and now firstNumber and secondNumber are the same.
To be clear: I just want this problem solved before I delve into the other operators, so please don't pay attention to the other operators like minus and multiplication.
A nudge in the right direction would be nice! Thanks in advance.
let displayBox = document.getElementById("displayBox");
let pressButton = document.querySelectorAll(".column");
let turnOn = document.getElementById("turnOn");
let minus = document.getElementById("minus");
let plus = document.getElementById("plus");
let firstNumber = Number();
let secondNumber = Number();
turnOn.addEventListener("click", function() {
displayBox.textContent = "CALCULATOR ON. GIVE FIRST NR.";
console.log("launching function listenFirst");
listenFirst();
});
let listenFirst = () => {
console.log("launched listenFirst");
for (var i = 0; i < pressButton.length; i++) {
pressButton[i].addEventListener("click", function() {
firstNumber = displayBox.textContent = Number(this.id);
waitForOperator(firstNumber);
});
}
};
let listenSecond = () => {
console.log("launched listenSecond");
console.log(`first number is still ${firstNumber}`)
console.log(`waiting for you to press second number`)
for (var i = 0; i < pressButton.length; i++) {
pressButton[i].addEventListener("click", function() {
secondNumber = displayBox.textContent = Number(this.id);
console.log(`After click on second number, first number is ${firstNumber} and second number is ${secondNumber}`)
});
}
console.log(
`Now first number is ${firstNumber} and second number is ${secondNumber}`
);
};
let waitForOperator = () => {
console.log("launched waitForOperator");
console.log(`First number is ${firstNumber}`);
console.log("Waiting for you to press plus");
plus.addEventListener("click", function() {
listenSecond(firstNumber);
});
};
let calculateSum = () => {
console.log(`Second number is ${secondNumber}`);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Hello Bulma!</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"
/>
<script
defer
src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"
></script>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<section class="section">
<h1 class="title has-text-centered" id="titleText">Calculator.</h1>
<div class="container">
<div class="field">
<a class="button is-fullwidth is-static" id="displayBox"></a><a class="button is-success" id="turnOn">ON</a>
</div>
<div class="calculator">
<div class="columns">
<div class="column" id="7">7</div>
<div class="column" id="8">8</div>
<div class="column" id="9">9</div>
<div class="column" id="minus">-</div>
</div>
<div class="columns">
<div class="column" id="4">4</div>
<div class="column" id="5">5</div>
<div class="column" id="6">6</div>
<div id="plus">+</div>
</div>
<div class="columns">
<div class="column" id="1">1</div>
<div class="column" id="2">2</div>
<div class="column" id="3">3</div>
<div class="column" id="equals">=</div>
</div>
<div class="columns">
<div class="column" id="0">0</div>
<div class="column" id="dot">.</div>
</div>
</div>
</div>
</section>
<script src="script.js"></script>
</body>
</html>
You never remove the event listener you added to number number buttons in listenFirst. So when the user presses the buttons after waitForOperator both the code in listenFirst and listenSecond runs. listenFirst call waitForOperator again.
JavaScript: remove event listener Have a look at this answer for how to remove event listeners.

Categories