Home > OS >  How to toggle each button separately on multiple li elements?
How to toggle each button separately on multiple li elements?

Time:02-03

I am working on project and my goal is to toggle each individual li element by clicking toggle button. I managed to do this so far but it's working only on first li element. Can you help me with this code?

<li id="liEl">Target This element</li>
<button id="Btn">toggle</button>

<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>

<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>
.done {
  text-decoration: line-through;
  text-decoration-thickness: 0.2rem;
  text-decoration-color:red;
}
Btn= document.getElementById("Btn");
liEl= document.getElementById("liEl");

const toggleDoneClass = () => {

  liEl.classList.toggle('done');
};

Btn.addEventListener('click', toggleDoneClass);

CodePudding user response:

id attribute must be unique. you can use class instead of that.

HTML

<li >Target This element</li>
<button >toggle</button>

<li  >Target This element</li>
<button >toggle</button>

<li  >Target This element</li>
<button >toggle</button>

You must select all buttons and then add Event Listener to each one by a loop.

Javascript

var btns = document.getElementsByClassName("btn");

for (let i = 0; i < btns.length; i  ) {
    btns[i].addEventListener("click", () => {
         // Previous is li because li is before button
         btns[i].previousElementSibling.classList.toggle("done");
    });
}

Now this is Working.

CodePudding user response:

You are giving the same ids to all the buttons and li instead of id use class names

btns= document.getElementsByClassName("btn");

it will select all the classes which contain buttons

for(let index = 0;index < btns.length; index  ){
   btns[index].onclick = (evt) =>{
  evt.target.previousElementSibling.classList.toggle("done")
    }
}

looping all the classes on which you will click it will take that element and then get their previous child which is li and toggle class on that

btns= document.getElementsByClassName("btn");

for(let index = 0;index < btns.length; index  ){
   btns[index].onclick = (evt) =>{
  evt.target.previousElementSibling.classList.toggle("done")
    }
}
.done {
  text-decoration: line-through;
  text-decoration-thickness: 0.2rem;
  text-decoration-color:red;
}
<li id="" >Target This element</li>
<button  >toggle</button>

<li id="" >Target This element</li>
<button  >toggle</button>

<li id="lEl" >Target This element</li>
<button  >toggle</button>

CodePudding user response:

IDs should be unique in a page so maybe switch those to classes.

If you want the buttons you should add them within the list item elements.

You can attach one listener to the <ul> element and have that catch events from its children as they "bubble up" the DOM. (This is known as event delegation.)

When a click event is fired you can retrieve the specific element that was clicked with event.target, check that it's a button element, find the closest list item element to that button, and then toggle its class.

const list = document.querySelector('ul');
list.addEventListener('click', toggleDoneClass);

function toggleDoneClass(e) {
  if (e.target.matches('button')) {
    e.target.closest('li').classList.toggle('done');
  }
}
.done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
li button { margin-left: 0.5em; }
<ul>
  <li >
    Target This element
    <button type="button">Toggle</button>
  </li>
  <li >
    Target This element
    <button type="button">Toggle</button>
  </li>
  <li >
    Target This element
    <button type="button">Toggle</button>
  </li>
</ul>

But, ultimately, you don't really need the buttons.

const list = document.querySelector('ul');
list.addEventListener('click', toggleDoneClass);

function toggleDoneClass(e) {
  if (e.target.matches('li')) {
    e.target.classList.toggle('done');
  }
}
.done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
li:hover { cursor: pointer; }
<ul>
  <li >Target This element</li>
  <li >Target This element</li>
  <li >Target This element</li>
</ul>

  • Related