Reputation: 527
I'm trying to create a vanilla JS to do app. Users can input todo item(s) and click on them to mark 'em complete. But for some reason the "complete" class is toggling. It toggles on li items that are present previously but not on newly created li
const li = document.querySelectorAll('li');
const btn = document.querySelector('button');
var list = document.getElementById('container');
const inputTxt = document.querySelector('input');
const val = document.getElementById('item');
//add todo function
function btnClick() {
var inputText = inputTxt.value;
var entry = document.createElement('li');
entry.className = "incomplete";
entry.appendChild(document.createTextNode(inputText));
list.appendChild(entry);
}
function ToggleClass(event) {
var check = event.target;
var find = check.closest('li');
this.classList.toggle('complete');
console.log(find);
}
btn.addEventListener('click', btnClick);
li.forEach(item => item.addEventListener('click', ToggleClass));
.todo {
text-align: center;
}
ul {
list-style: none;
}
.complete {
color: green;
}
li:hover {
cursor: pointer;
}
.complete {
position: relative;
}
.complete:before {
position: absolute;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: inherit;
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
transform: rotate(-5deg);
}
<body>
<section class="todo">
<div class="wrap">
<input type="text" name="todo_text" id="item">
<button>Add item</button>
<ul id="container">
<li class="todo_item complete">Some todo item text</li>
<li class="todo_item complete">Some todo item text</li>
<li class="todo_item incomplete">Some todo item text</li>
</ul>
</div>
</section>
My guess, May be it has to do something with creating the textNode.
Upvotes: 0
Views: 1060
Reputation: 370779
Use event delegation on the ul
instead (at the moment, your listeners are on each button instead, but you're not adding new listeners when items are added):
const li = document.querySelectorAll('li');
const btn = document.querySelector('button');
var list = document.getElementById('container');
const inputTxt = document.querySelector('input');
const val = document.getElementById('item');
list.addEventListener('click', (e) => {
const { target } = e;
if (target.tagName !== 'LI') return;
target.classList.toggle('complete');
});
//add todo function
function btnClick() {
var inputText = inputTxt.value;
var entry = document.createElement('li');
entry.className = "incomplete";
entry.appendChild(document.createTextNode(inputText));
list.appendChild(entry);
}
btn.addEventListener('click', btnClick);
.todo {
text-align: center;
}
ul {
list-style: none;
}
.complete {
color: green;
}
li:hover {
cursor: pointer;
}
.complete {
position: relative;
}
.complete:before {
position: absolute;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: inherit;
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
transform: rotate(-5deg);
}
<body>
<section class="todo">
<div class="wrap">
<input type="text" name="todo_text" id="item">
<button>Add item</button>
<ul id="container">
<li class="todo_item complete">Some todo item text</li>
<li class="todo_item complete">Some todo item text</li>
<li class="todo_item incomplete">Some todo item text</li>
</ul>
</div>
</section>
Upvotes: 1
Reputation: 8422
You need to add the event listener to newly created elements inside the btnClick()
function, otherwise the new elements won't have the listener.
So:
function btnClick() {
var inputText = inputTxt.value;
var entry = document.createElement('li');
entry.className = "incomplete";
entry.addEventListener('click', ToggleClass);
entry.appendChild(document.createTextNode(inputText));
list.appendChild(entry);
}
Upvotes: 1