Home > OS >  I am unable to add event listener to li which is created by JS
I am unable to add event listener to li which is created by JS

Time:10-04

I am unable to adding event listener to list item which is created by JavaScript.

I am trying to add a event listener to list item such that if I double click to any list item it will remove that particular list item from the DOM.

// Declaring Variables

let inputbtn = document.getElementById('input-but');
let addBtn = document.getElementById('add-button');
let list = document.getElementById('text');
addBtn.addEventListener('click', getVal)
// Adding Function to Add New task  

function getVal() {
    let value = inputbtn.value;
    if (value === "") {
        alert("Please fill out this field.")
    }
    else {
        let newElement = document.createElement('li')
        let liText = document.createTextNode(value)
        newElement.appendChild(liText)
        list.appendChild(newElement)
    }
    document.myForm.reset()
}


// Removing Task by ___________
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-do List Trial</title>
    <link rel="stylesheet" href="Trial.css">
</head>
<body>
    <h3>To do list</h3>
    <form action="" name="myForm">
        <input type="text" id="input-but" required>
        <input type="button" id="add-button" value="Add Task">
        <ul id="text"></ul>
    </form>

    <!-- JavaScript Source -->
    <script src="Trial.js"></script>
</body>
</html>

CodePudding user response:

Instead of adding listeners to each list item add one to the ul element and use event delegation to catch dblclick events as they bubble up the DOM.

let inputbtn = document.getElementById('input-but');
let addBtn = document.getElementById('add-button');
let list = document.getElementById('text');
addBtn.addEventListener('click', getVal)

list.addEventListener('dblclick', handleClick, false);

function handleClick(e) {
  if (e.target.nodeName === 'LI') {
    e.target.remove();
  }
}

function getVal() {
  let value = inputbtn.value;
  if (value === "") {
    alert("Please fill out this field.")
  } else {
    let newElement = document.createElement('li')
    let liText = document.createTextNode(value)
    newElement.appendChild(liText)
    list.appendChild(newElement)
  }
}
<h3>To do list</h3>
<input type="text" id="input-but" required>
<input type="button" id="add-button" value="Add Task">
<ul id="text"></ul>

CodePudding user response:

In this scenario event delegation can come to the rescue. Create one listener function and let that function determine if an action should be performed. Add the listener on the document level for the event types you want the listener to handle.

Here's a snippet to play with.

See also

document.addEventListener(`click`, handle);
document.addEventListener(`dblclick`, handle);

function handle(evt) {
  if (evt.target.id === `add-button`) {
    const inp = document.querySelector(`#input-but`);
    const value = inp.value.trim();

    if (value) {
      inp.removeAttribute(`placeholder`);
      document.querySelector(`ul#text`)
        .insertAdjacentHTML(`beforeend`,
          `<li class="point">${value}</li>`);
      return inp.value = ``;
    }

    inp.value = ``;
    return inp.setAttribute(`placeholder`, `Hey, give me some text!`)
  }

  if (evt.type === `dblclick` && evt.target.closest(`li`)) {
    evt.preventDefault();
    evt.target.closest(`li`).remove();
  }
}
.point {
  cursor: pointer;
}

.point:hover::after {
  content: ' (double click to remove)';
  color: red;
}
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>To-do List Trial</title>
  <link rel="stylesheet" href="Trial.css">
</head>

<body>
  <h3>To do list</h3>
  <form action="" name="myForm">
    <input type="text" id="input-but" required>
    <input type="button" id="add-button" value="Add Task">
    <ul id="text"></ul>
  </form>

  <!-- JavaScript Source -->
  <script src="Trial.js"></script>
</body>

</html>

CodePudding user response:

You can add a listener to the newElement before appending to the parent.

newElement.addEventListener('dblclick', () => newElement.remove());

But a simpler solution might be to use event delegation and add a single listener to the parent ul.

list.addEventListener('dblclick', (e) => {
  if (e.target.closest('li')) {
    e.target.closest('li').remove();
  }
})

CodePudding user response:

just add event listener to the created list item.

newElement.addEventListener("dblclick", function() {

  newElement.remove();

});

it works!

  • Related