-2

I have a table with edit button, every table contains an edit button with the different input field value, I need to get the different value of the input field when different edit buttons are hit. My code is getting the same value again and again not getting the random values, Here is my code of table

<tr>
    <td>64</td>
    <td>2</td>
    <td>2₪</td>
    <input type="hidden" name="idd" value="64" id="main-id">
    <td>
        <span id="editBtn" class="editBtn 64" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
    <span id="deleteBtn" class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
</tr>
<tr>
    <td>65</td>
    <td>25</td>
    <input type="hidden" name="idd" value="65" id="main-id">
    <td>
        <span id="editBtn" class="editBtn 65" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
        <span id="deleteBtn" class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
</tr>

Within this table when I try to edit each time using jquery it bring up the first value of the hidden field which is 64. Below is the jQuery which I used to pull the value of the hidden field.

var bla = $('#main-id').val();
alert (bla);
Abbasi
  • 588
  • 1
  • 7
  • 26
  • 1
    [Does ID Have To Be Unique In The Whole Page?](https://stackoverflow.com/questions/9454645/does-id-have-to-be-unique-in-the-whole-page) – Taplar Jan 23 '20 at 22:16
  • 2
    IDs must be unique to the document. Two elements cannot share the same ID as you have it in the code. – Heretic Monkey Jan 23 '20 at 22:16
  • Use classes instead for identifiers that repeat. Also, `alert bla;` <= wha? – Taplar Jan 23 '20 at 22:16
  • Changing id to class dose not bring the value of the edit button it, every time I click the edit button it brings the value of the first hidden field – Abbasi Jan 23 '20 at 22:20
  • When I click the hidden button the value of the hidden filed of that table should pull up that's not happening – Abbasi Jan 23 '20 at 22:21
  • Changing the ids to classes is not the complete solution. Once you do that, you have to start implementing contextual lookups for the elements that are clicked, to find the related elements. – Taplar Jan 23 '20 at 22:24
  • Can you please give me an example of how to do this? – Abbasi Jan 23 '20 at 22:27
  • Are you just trying to get the row number of the table? – Steve Jan 23 '20 at 22:43

1 Answers1

1

$('#editBtn').on('click', function(e){
  console.log($('#main-id').val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>64</td>
    <td>2</td>
    <td>2₪</td>
    <input type="hidden" name="idd" value="64" id="main-id">
    <td>
      <span id="editBtn" class="editBtn 64" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span id="deleteBtn" class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
  <tr>
    <td>65</td>
    <td>25</td>
    <input type="hidden" name="idd" value="65" id="main-id">
    <td>
      <span id="editBtn" class="editBtn 65" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span id="deleteBtn" class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
</table>

So what is the issue with this logic?

IDs must be unique

The big issue here is the repeated usage of the same ids. Ids, by web standards, should be unique per page. This is detailed in the web standards, and reinforced by existing methods such as getElementById. Notice that the method is "getElement", not "getElements".

So how do we address this issue? Any time you have the need to identify elements, and those element "logically" repeat on the page, that is a potential use case of a class. Classes can repeat.

$('.editBtn').on('click', function(e) {
  console.log($('.main-id').val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
      64
      <input type="hidden" name="idd" value="64" class="main-id">
    </td>
    <td>2</td>
    <td>2₪</td>
    <td>
      <span class="editBtn 64" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
  <tr>
    <td>
      65
      <input type="hidden" name="idd" value="65" class="main-id">
    </td>
    <td>25</td>
    <td>
      <span class="editBtn 65" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
</table>

So this second snippet has changed to use classes, yet the same behaviour remains. Why is that? That is because val() will only return the first value of all the results of the selector. So while we find all the elements with the class of main-id, it only gets the first one logged. How do we address that issue?

Contextual lookups

When ever you perform an operation such as $('.main-id') what jQuery actually does is $(document).find('.main-id'). It implicitly uses the document as the context. The context is the element by which the children will be searched for within.

So with that in mind, in relation to our issue, what is our context? Our context is each row. So in order to grab the specific main-id that we want, we should use a contextual lookup to find it. This would look something like the following.

$('.editBtn').on('click', function(e) {
  console.log($(e.target).closest('tr').find('.main-id').val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
      64
      <input type="hidden" name="idd" value="64" class="main-id">
    </td>
    <td>2</td>
    <td>2₪</td>
    <td>
      <span class="editBtn 64" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
  <tr>
    <td>
      65
      <input type="hidden" name="idd" value="65" class="main-id">
    </td>
    <td>25</td>
    <td>
      <span class="editBtn 65" style="cursor: pointer; text-decoration: underline;">Edit</span>
    </td>
    <td>
      <span class="deleteBtn" style="cursor: pointer; text-decoration: underline;">Delete</span>
    </td>
  </tr>
</table>

Clicking the edit buttons now logs the correct value. How does that work? So the first thing we do is wrap the e.target (the element that was clicked) in a jQuery object, so we have access to the jQuery methods. We then use the closest() method to find that elements parent tr. That tr is our context. From there, we perform a find for the .main-id, which will only find the main id within our specific row, and boom. You have the element/value you want.

Taplar
  • 24,788
  • 4
  • 22
  • 35