2

Given this HTML:

 <ul class="myList">
   <li class="List" data-pos="Noah">
      <label><input class="text">pass</label>
   </li>
   <li class="List" data-pos="Liam">
      <label><input class="text">fail</label>
   </li>
   <li class="List" data-pos="James">
      <label><input class="text">average</label>
  </li>
 </ul>

I want to create a JavaScript function that will add new class to an element when the user clicks on it, based on the data-pos attribute of the element.

   click on "Noah"  add class Noah1
   click on "Liam"  add class Liam1
   click on "James" add class James1

Expected result after clicking all the elements:

 <ul class="myList">
   <li class="List Noah1" data-pos="Noah">
       <label><input class="text">pass</label>
   </li>
   <li class="List Liam1" data-pos="Liam">
       <label><input class="text">fail</label>
   </li>
   <li class="List James1" data-pos="James">
       <label><input class="text">average</label>
   </li>
 </ul>

I tried the following javascript. It results in <label class="null1"> instead of <li class="List Noah1"> or <li class="List Liam1"> or <li class="List James1">

function clickEvent(event) {
    event.target.classList.add(event.target.getAttribute('data-pos') + "1")
    console.log(event.target.classList)
}

document.querySelector('ul').addEventListener('click', clickEvent, false);
1
  • Put const target = event.target.closest('li'); at the beginning of the click handler, and use target instead of event.target in the later code. Notice also, that you've to remove the harcoded "name classes". This way you can click what ever element inside a list element, and the code will find the closest list element in the parent chain. It's also good to check, that target was actually found, otherwise the code will trigger an error, if you've somehow managed to click outside of an list element but still inside the ul. Commented Feb 2, 2021 at 17:13

1 Answer 1

2

You have nested elements. The click event fires on the inner element (label) and then bubbles up to the ul element.

You need to step to the parent element if the label receives the click.

function clickEvent(event) {
  let element = event.target
  if(element.tagName === 'LABEL') {
    element = event.target.parentElement;
  }
  element.classList.add(element.getAttribute('data-pos') + "1")
  console.log(element.classList)
}
Sign up to request clarification or add additional context in comments.

3 Comments

Sir it is working perfect but it is also add unnecessary <input class="text null1"> we are add in codepen to this please reply [codepen.io/MrUmang/pen/WNoQvvq] And this javascript code working 1st row only, after 1st row it is not working on 2nd, 3rd. 4th,... row please how can solve this problem @randy casburn
Sorry For That Link url codepen.io/MrUmang/pen/WNoQvvq @randy casburn
Still a 404. I will tell you that the reason you receive null1 as a class name is because this code: element.getAttribute('data-pos)` returns null. That means that LI does not have an attribute named data-pos. it would be best to use the dataset API for accessing the data- attributes anyway. Try that in place of .getAttribute(). To use dataset change element.getAttribute('data-pos)` to element.dataset.pos.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.