I am trying to add an increasing count number when a button is clicked, within the container <div>.
My code is not working, what am I missing?
let taskCounter = 0;
let addTaskFunction = () => {
const container = document.querySelector(".container");
taskCounter++;
let counterInDiv = document.createElement(`<div> ${taskCounter} </div>`);
container.appendChild(counterInDiv);
};
document.getElementById('addTask').addEventListener("click", () => {
addTaskFunction();
});
<h1>Your tasklist for today</h1>
<div class="container">
<div class="inputPart">
<input id="taskInput" value="" placeholder="Fill in the following task here" />
<button id="addTask">Add task</button>
<button id="removeAllTasks">Delete tasks</button>
</div>
</div>
You need to use the tag name (div) for document.createElement then set the innerHTML instead of using the actual HTML code.
let taskCounter = 0;
let addTaskFunction = () => {
const container = document.querySelector(".container");
taskCounter++;
let counterInDiv = document.createElement("div"); // <--HERE
counterInDiv.innerHTML = taskCounter;
container.appendChild(counterInDiv);
};
document.getElementById('addTask').addEventListener("click", () => {
addTaskFunction();
});
<body>
<h1>Your tasklist for today</h1>
<div class="container">
<div class="inputPart">
<input id="taskInput" value="" placeholder="Fill in the following task here" />
<button id="addTask">Add task</button>
<button id="removeAllTasks">Delete tasks</button>
</div>
</div>
<script src="app.js"></script>
</body>
I believe that this is the code you want:
let taskCounter = 1;
const taskList = document.getElementById("taskList");
const addTaskBtn = document.getElementById("addTask");
addTaskBtn.addEventListener("click", () => {
let task = document.getElementById("taskInput").value;
let counterInDiv = document.createElement("div");
counterInDiv.textContent = `${taskCounter++}: ${task}`;
taskList.appendChild(counterInDiv);
});
const deleteTasksBtn = document.getElementById("removeAllTasks");
deleteTasksBtn.addEventListener("click", () => {
taskList.innerHTML = "";
taskCounter = 1;
});
<h1>Your tasklist for today</h1>
<div class="container">
<div class="inputPart">
<input id="taskInput" placeholder="Fill in the following task here" />
<button id="addTask">Add task</button>
<button id="removeAllTasks">Delete tasks</button>
</div>
<div id="taskList"></div>
</div>
I made a few changes:
You do not need a function for the event listener, you can put the code inside an anonymous function that is passed to the event listener
taskCounter should start at 1, not 0
If you want the delete tasks button to work, then you should put the tasks inside a different container that can be easily cleared. I used one with the ID of "taskList"
document.querySelector() only selects a single element, but you gave it a class of "container". If multiple <div>s have the class "container", then you will run into problems.
document.createElement takes a tag name as the parameter, not HTML code. You should use document.createElement("div") then set the .textContent to whatever you want.
Related
I'm super new to JS, HTML, and CSS. I've looked up many answers but can't quite understand the context when applied to my situation. Button 2 is what needs the onClick function, but I'm not sure how to implement the strikethrough aspect. Thank you!
My JS goes as follows:
window.onload = function() {
document.getElementById("submit-btn").addEventListener("click", function() {
let text = document.getElementById("text-box").value;
let li = document.createElement("li");
li.id = "liId";
li.innerText = text;
document.getElementById("unordered-list").appendChild(li);
let button = document.createElement("button");
button.innerText = "X";
button.setAttribute = ("id", "b1");
li.appendChild(button);
button.addEventListener("click", () => li.parentNode.removeChild(li));
document.getElementById("unordered-list").appendChild(li);
let button2 = document.createElement("button");
button2.innerText = "Done";
button2.id = "b2";
li.appendChild(button2);
li.appendChild(button);
li.appendChild(button2);
});
document.getElementById("b2").addEventListener("click", function () {
document.getElementById("liId").style = "text-decoration: line-through;"
});
}
HTML:
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My First Project</title>
</head>
<body>
<script src="script.js"></script>
<header id="to-do-box">
<h1>To-Do List</h1>
<div id="top-half">
<form>
<input type="text" id="text-box" placeholder="Add an item!">
<button type="button" id="submit-btn">Submit</button>
<button type="button" id="clear-field-btn">Clear field</button>
</form>
</div>
</header>
<div id="ul">
<ul id="unordered-list"></ul>
</div>
</body>
</html>
You can do this by implementing an event listener that activates on button click. This will delete the first list element that is shown.
document.getElementById("submit-btn").addEventListener("click", function() {
let text = document.getElementById("text-box").value;
let li = document.createElement("li");
li.setAttribute = ("id", "list");
li.id = "liId";
li.innerText = text;
document.getElementById("unordered-list").appendChild(li);
let button = document.createElement("button");
button.innerText = "X";
button.setAttribute = ("id", "b1");
li.appendChild(button);
button.addEventListener("click", () => li.parentNode.removeChild(li));
document.getElementById("unordered-list").appendChild(li);
let button2 = document.createElement("button");
button2.innerText = "Done";
button2.id = "b2";
button2.classList.add('buttonClass');
li.appendChild(button2);
li.appendChild(button);
li.appendChild(button2);
document.querySelectorAll('.buttonClass').forEach(item => {
item.addEventListener('click', event => {
change()
})})});
function change() {
document.querySelectorAll("#b2").forEach(item => {
item.parentNode.style = "text-decoration: line-through;"
})}
document.getElementById("clear-field-btn").addEventListener('click', event => {
document.querySelectorAll("#b2").forEach(item => {
item.parentNode.remove();
})
})
<html>
<body>
<header id="to-do-box">
<h1>To-Do List</h1>
<div id="top-half">
<form>
<input type="text" id="text-box" placeholder="Add an item!">
<button type="button" id="submit-btn">Submit</button>
<button type="button" id="clear-field-btn">Clear field</button>
</form>
</div>
</header>
<div id="ul">
<ul id="unordered-list"></ul>
</div>
</body>
</html>
Keep in mind though, this will only work for one of the list elements, if you want to discard all of the list elements if the user has multiple, you will need to utilize a forEach function.
I want to show div content on button click .and thee is 3 different button following 3 different content. I tried this logic and it made my code lengthy. how to simplify is code using loop or condition?
function replace1(){
document.getElementById("con1").style.visibility="visible";
document.getElementById("con2").style.visibility="hidden";
document.getElementById("con3").style.visibility="hidden";
document.getElementById("con4").style.visibility="hidden";
document.getElementById("con5").style.visibility="hidden";
document.getElementById("con6").style.visibility="hidden";
}
function replace2(){
document.getElementById("con1").style.visibility="hidden";
document.getElementById("con2").style.visibility="visible";
document.getElementById("con3").style.visibility="hidden";
document.getElementById("con4").style.visibility="hidden";
document.getElementById("con5").style.visibility="hidden";
document.getElementById("con6").style.visibility="hidden";
}
function replace3(){
document.getElementById("con1").style.visibility="hidden";
document.getElementById("con2").style.visibility="hidden";
document.getElementById("con3").style.visibility="visible";
document.getElementById("con4").style.visibility="hidden";
document.getElementById("con5").style.visibility="hidden";
document.getElementById("con6").style.visibility="hidden";
}
enter image description here
.active-button {
background: red;
}
<button class="replace-button" onclick="replace(1, this)"></button>
<button class="replace-button" onclick="replace(2, this)"></button>
<button class="replace-button" onclick="replace(3, this)"></button>
function replace(visibleIndex, _this) {
const buttons = document.querySelectorAll('.replace-button');
buttons.forEach(button => button.classList.remove("active-button"));
_this.classList.add("active-button");
for(let i = 1; i < 7; i++) {
let element = document.getElementById("con" + i)
i === visibleIndex ? element.style.visibility = "visible" : element.style.visibility = "hidden";
}
}
Use a class - add class="con" to each element - also use hidden instead of visibility since the hidden divs still will take up space
const toggle = id => cons
.forEach(con => con.hidden = con.id !== id);
Here is a version that will change the colour of the button too.
You will need to use hidden or display:none to have the divs stay in one place
window.addEventListener('DOMContentLoaded', function() {
const cons = document.querySelectorAll('.con');
const buts = document.querySelectorAll('.toggle');
const toggle = id => cons
.forEach(con => con.hidden = con.id !== id);
document.getElementById('nav').addEventListener('click', function(e) {
const tgt = e.target.closest('button');
if (tgt.classList.contains('toggle')) {
toggle(tgt.dataset.id)
buts.forEach(but => but.classList.remove('active'));
tgt.classList.add('active');
}
})
})
.active {
background-color: green;
}
<nav id="nav">
<button type="button" class="toggle" data-id="con1">Con 1</button>
<button type="button" class="toggle" data-id="con2">Con 2</button>
<button type="button" class="toggle" data-id="con3">Con 3</button>
</nav>
<div id="con1" class="con" hidden>
<h1>Con 1</h1>
</div>
<div id="con2" class="con"hidden>
<h1>Con 2</h1>
</div>
<div id="con3" class="con" hidden>
<h1>Con 3</h1>
</div>
Although my code works and I understand all of it, what I am stumped on is why parentElement works for the code below.
By my understanding, the parent element of the button element should be the div with class "child-div", so why then is the code still giving me the correct answer for each "shop-item-title" when clicking the "Okay" button?
Any clarity will be highly appreciated:
let addToCart = document.getElementsByClassName("button-ok");
function addToCartClicked(event) {
let button = event.target;
let shopItem = button.parentElement;
let title = shopItem.getElementsByClassName("shop-item-title")[0].innerText;
console.log(title);
}
for (let i = 0; i < addToCart.length; i++) {
let button = addToCart[i];
button.addEventListener("click", addToCartClicked);
}
<div class="body-container">
<div class="child-div">
<p class="shop-item-title">Chocolate</p>
<br />
<button class="button-ok">Okay</button>
</div>
<div class="child-div">
<p class="shop-item-title">Coke</p>
<br />
<button class="button-ok">Okay</button>
</div>
</div>
I'm learning JavaScript and this is a practice scenario for me.
What I have already is a button that clones content, and within that content that has been cloned, there is a button to remove it.
When I click the button that prompts you to remove the content, it removes the first set of content.
What I want to happen is when you click the button that prompts you to remove the content, it removes the content related to that button and nothing else.
This is the CodePen link.
https://codepen.io/JosephChunta/pen/YzwwgvQ
Here is the code.
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent() {
var x = document.getElementById("content").parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden {
display: none;
}
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent()">Remove this</button>
<hr />
</div>
</div>
</div>
When you'r trying to remove by ID, it takes the first ID it finds.
To remove the correct content, send this onclick.
<button onclick="removeContent(this)">Remove this</button>
And handle it in your function:
function removeContent(el) {
el.parentNode.remove();
}
Example:
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent(el) {
el.parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden { display: none; }
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent(this)">Remove this</button>
<hr />
</div>
</div>
</div>
In your remove button, do this:
<!-- The "this" keyword is a reference to the button element itself -->
<button onclick="removeContent(this)">Remove this</button>
And in your javascript:
function removeContent(element) {
element.parentNode.remove();
}
I have made a little javascript to-do app in order to get better at the language. I am trying to create a counter which increments each time a task is added to the ordered list, but it does not work. Here is my code:
var button = document.getElementById('add-button');
button.addEventListener('click', function() {
var item = document.getElementById('input').value;
var text = document.createTextNode(item);
var newItem = document.createElement('li');
newItem.appendChild(text);
document.getElementById('todoList').appendChild(newItem);
var count = 0;
count++;
document.getElementById('counter').innerHTML = count;
var removeTask = document.createElement('img');
removeTask.setAttribute('src', '/images/trash.jpg');
removeTask.setAttribute('id', 'trash');
removeTask.addEventListener('click', function() {
newItem.parentNode.removeChild(newItem);
});
newItem.appendChild(removeTask);
});
<div class="header">
<form>
<h2>Todo App</h2>
<p>Add a new todo</p>
<input type="text" id="input" placeholder="Enter an activity......">
<button type="button" id="add-button">Add Task</button>
</form>
</div>
<ol id="todoList">
<h1>Things to do:</h1>
<div id="counter">0</div>
</ol>
Right now it increments to 1 when one clicks but it ends there. I tried making a for loop that loops until the length of the newItem but that did not work at all. How can I make it increment on each time an item is added?
You need to define count outside of the scope of the event listener, otherwise you will always increment 0 by 1 for every item added (and 0+1 is always 1). Put the declaration outside of the listener, and increment that value:
var button = document.getElementById('add-button');
var count = 0;
button.addEventListener('click', function() {
var item = document.getElementById('input').value;
var text = document.createTextNode(item);
var newItem = document.createElement('li');
newItem.appendChild(text);
document.getElementById('todoList').appendChild(newItem);
count++;
document.getElementById('counter').innerHTML = count;
var removeTask = document.createElement('img');
removeTask.setAttribute('src', '/images/trash.jpg');
removeTask.setAttribute('id', 'trash');
removeTask.addEventListener('click', function() {
newItem.parentNode.removeChild(newItem);
});
newItem.appendChild(removeTask);
});
<div class="header">
<form>
<h2>Todo App</h2>
<p>Add a new todo</p>
<input type="text" id="input" placeholder="Enter an activity......">
<button type="button" id="add-button">Add Task</button>
</form>
</div>
<ol id="todoList">
<h1>Things to do:</h1>
<div id="counter">0</div>
</ol>