-1

I click on a button which has a class 'return' and I want to get an id of the card. Here is a peace of code.

$('.return').on('click', () => {

  let a = $('.return').siblings();
  console.log(a);

})
for (let card of cards) { 
table += `
<tr>
  <th scope="row">${card._id}</th>
  <td>${card._visitor}</td>
  <td>${card._bookName}</td>
  <td>${card._borrowDate}</td>
  <td>${card._returnDate==='not fetched'?'' + '
    <button class="return"></button>':card._returnDate}
  </td>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
John
  • 33
  • 5
  • 1
    The button has no siblings. – Andreas Feb 26 '21 at 09:10
  • [jQuery Learning Center](https://learn.jquery.com/) -> [Traversing](https://learn.jquery.com/using-jquery-core/traversing/) – Andreas Feb 26 '21 at 09:12
  • `$('.return').siblings()` will give you all the siblings for *all* the buttons - not what you want (as you know, just explaining what it does) – freedomn-m Feb 26 '21 at 09:36
  • It's not a (direct) duplicate, but this explains arrow functions and `this`: https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-interchangeable. Also useful (linked from that question) https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/es6%20&%20beyond/ch2.md#not-just-shorter-syntax-but-this – freedomn-m Feb 26 '21 at 09:38

3 Answers3

0

You can do it like this:

let a = $(this).parent().prevAll("th").text();

$(this) <- refers to the button that was clicked.
.parent() <- to access the td
.prevAll("th") <- to find the th that comes before you td
.text() <- to get the text aka ${card._id}

Problem is that your button is not the sibling of your th

Demo

$('.return').on('click', function() {

  let a = $(this).parent().prevAll("th").text();
  console.log(a);

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<table>
  <tr>
    <th scope="row">${card._id}</th>
    <td>${card._visitor}</td>
    <td>${card._bookName}</td>
    <td>${card._borrowDate}</td>
    <td>${card._returnDate==='not fetched'?'' + '
      <button class="return"></button>':card._returnDate}
    </td>
    </tr>
</table>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
  • your explanation is good but it is not working in my case. I can't find this.parent(). I get this jQuery.fn.init [prevObject: j…y.fn.init, context: undefined] – John Feb 26 '21 at 09:28
  • Because your original code uses `()=>` for the click event, so `this` is not the button. **Don't use `()=>` for click events** - change to `.click(function() {` (other options available) – freedomn-m Feb 26 '21 at 09:29
  • @freedomn-m ` Don't use ()=> for click events ` well...that depends on what you want to do in those click functions. If you want to use the clicked element, yes. Don't use arrow functions. But if you want to use the class or the scope or something else...then it's ok to use arrow functions. – Mihai T Feb 26 '21 at 09:38
  • @MihaiT agreed, but I would say, probably 100% (yes 100%) of recent questions asking why their click event isn't working is because `()=>` - so it's an easy rule. As with all rules, there are exceptions. – freedomn-m Feb 26 '21 at 09:40
0

One option is to add the id to the button

<button class="return" data-id="${card._id}"..

then you can access that id without needing to traverse.

Note you're also using ()=> in the click event, so you won't be able to use this to reference the button. Change to function() to get this, giving:

$('.return').on('click', function() {

  let id = $(this).data("id");
  console.log(id);

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td><button class="return" data-id="1">return</button>
      </td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td><button class="return" data-id="2">return</button>
      </td>
    </tr>
  </tbody>
  <tr>
    <th scope="row">752</th>
    <td><button class="return" data-id="752">return</button>
    </td>
  </tr>
</table>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
0

You can bypass jquery and use your script when adding cards to attach an onclick method to your button and retrieve the card id

const cards = [{
    _id: 1,
    _returnDate: "not fetched"
  },
  {
    _id: 2,
    _returnDate: "not fetched"
  }
]
const table = document.querySelector("table")
for (let card of cards) {
  table.innerHTML += ` <tr>
      <th scope="row">${card._id}</th>
      <td> <button class="return" onclick="buttonClick(${card._id});">Click Me</button></td>
      </tr>`
}

function buttonClick(cardId) {
  console.log("card id:", cardId)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
</table>
Mihai T
  • 17,254
  • 2
  • 23
  • 32
  • so you suggest using jquery ? what year is this ? :) You can say ' won't work if ... ' on every code solution to any problem – Mihai T Feb 26 '21 at 09:39
  • well if he already uses javascript to add HTML inside an element. Why not add an onclick function while you are at it ? – Mihai T Feb 26 '21 at 09:41
  • So you use `jquery` ( an entire library ) just so you can write `$("#idSelector")` instead of `document.getElementById('idSelector')` ? :)) that's some good ' coding ' advice there. – Mihai T Feb 26 '21 at 09:43