How to get an element from event target closest(name)

Viewed 11140

I'm not sure how to use event target closest([name="..."]) as I understand closest() should get the element after I change value in the input field to calculate, but the elements I get are null

function calculate(e) {
    if (e.target.name == 'qty') {
      var elemPrice = e.target.closest('[name="price"]') //***
      var elemAmount = e.target.closest('[name="amount"]') //***
      console.log(elemPrice)
      console.log(elemAmount)
      elemAmount.value = elemPrice.value * e.target.value
    }
}
document.addEventListener('DOMContentLoaded',function(){
    document.getElementsByName('qty').forEach(t => { t.addEventListener('change',calculate) })
})
<table>
      <tbody>
                <tr class="uk-hidden">
                    <td>1</td>
                    <td><input name="price"></td>
                    <td><input name="qty"></td>
                    <td><input name="amount"></td>
                </tr>
                <tr class="uk-hidden">
                    <td>2</td>
                    <td><input name="price"></td>
                    <td><input name="qty"></td>
                    <td><input name="amount"></td>
                </tr>
                <tr class="uk-hidden">
                    <td>3</td>
                    <td><input name="price"></td>
                    <td><input name="qty"></td>
                    <td><input name="amount"></td>
                </tr>
      </tbody>
</table>

I've tried

   ...
      var elemPrice = e.target.parentElement.previousElementSibling.lastElementChild  //***
      var elemAmount = e.target.parentElement.nextElementSibling.lastElementChild  //***
   ...

but I want to do like closest is there a way to do this ?

anyways Thank you in advance

2 Answers

Reading the docs is always a good idea. If we look at https://developer.mozilla.org/en-US/docs/Web/API/Element/closest it says:

The closest() method traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null.

So it does not do what you assumed: it only checks the path from your element to the document root. What you want is to find the closest <tr>, and then find the name=price element inside of that element:

e.target.closest(`tr`).querySelector(`[name=price]`)

Don't forget that with TypeScript you must be explicit about the type of element target is.

highlight($event: Event) {
  let tar = $event?.target as HTMLElement; // HTMLInputElement etc

  console.log(tar);
  // now TS allows access to expected HTMLElement methods like .closest
  console.log(tar.closest('div'));
}
Related