Home > OS >  Create an element with a click and remove it by a second click
Create an element with a click and remove it by a second click

Time:08-16

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:

  1. Add a variable indicating that the icon has been already added.
  2. 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>

  • Related