Getting the value of the input field using jquery

$('#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.

Leave a Comment