Still learning so bear with me.
I am building a test project where I have a simple input that I show it on the same page as a list. (grocery or to do list project) So when a user hits the ok button I create a new li inside a ul element. That goes ok. I want to implement the following though: When the user clicks on the new element (li) I want to change the text decoration to line-though and show a trash icon where it will remove this li element by clicking on it. I have managed to do that. The problem is that when the user clicks again on the new element (li) I get a second trash image. I want help to succeed in this: when a user clicks on the element while it has text-decoration = line-through to hide or remove the trash icon and make text-decoration none again.
Here is a code pen for this project to check out. Just insert a new item on the list and then click twice on it: https://codepen.io/dourvas-ioannis/pen/MWVBjNZ
This is the function I am using when the user hits the add button to add a list item:
function addToList(){
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function(){
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i >delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem(){
this.parentNode.remove();
}
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function() {
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i >delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
CodePudding user response:
- Add a variable indicating that the icon has been already added.
- Check if icon is added on click
- If yes - skip
- If not - set icon
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
// declare boolean variable
let hasTrashIcon = false
newListItem.addEventListener('click', function() {
// if has thrash icon skip
if (hasTrashIcon) return
// set has trash icon
hasTrashIcon = true
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i >delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
CodePudding user response:
Here's a quick example implementation of the approach I mentioned in the comments. I've just hacked it together quickly, so there's a small difference for the bin.
- I've used an img (without a src) instead of a 'character' from the font. I've styled the img to be 16x16 for the same reason. It also makes it visible instead of being 0x0 pixels. I also set the cursor.
"use strict";
window.addEventListener('load', onl oad, false);
function onl oad(evt) {
document.querySelector('button').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked(evt) {
let userText = document.querySelector('input').value;
let newLi = document.createElement('li');
newLi.textContent = userText;
newLi.addEventListener('click', onIncompleteItemClicked, false);
document.querySelector('ul').appendChild(newLi);
}
function onIncompleteItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = document.createElement('img');
binImg.addEventListener('click', onBinIconClicked, false);
clickedLi.appendChild(binImg);
clickedLi.removeEventListener('click', onIncompleteItemClicked, false);
clickedLi.addEventListener('click', onCompletedItemClicked, false);
}
function onCompletedItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = clickedLi.querySelector('img');
clickedLi.removeChild(binImg);
clickedLi.removeEventListener('click', onCompletedItemClicked, false);
clickedLi.addEventListener('click', onIncompleteItemClicked, false);
}
function onBinIconClicked(evt) {
let clickedBin = this;
let containingLi = clickedBin.parentNode;
containingLi.remove();
}
.itemComplete {
text-decoration: line-through;
}
li>img {
cursor: pointer;
width: 16px;
height: 16px;
}
<input value='blah-blah'></input><button>Add</button>
<ul></ul>