skip to Main Content

I want to update a record using AJAX, but when I click the button to edit the row I get the same data-id of the first row in the table element.

<table>
  <!-- this data inside php foreach loop displayed via ajax -->
  <tr>
    <td> <a href="<?= $row->id; ?>" id="edit_btn" data-id="<?= $row->id; ?>">edit</a></td>
    <td> <a href="<?= $row->id;?>'" id="delete_btn" data-id="<?= $row->id; ?>">delete</a></td>
  </tr>
</table>
$(function($) {
  edit();
})(jQuery);

function edit() {
  $(document).on('click', '#edit_btn', (e) => {
    e.preventDefault();
    var aid = $('#edit_btn').attr('data-id');
    // var aid = $('#edit_btn').data('id');
    alert(aid);
  });
}

3

Answers


  1. You should retrieve the data-id using the data method:

    var aid = $('#edit_btn').data('id');
    

    Warning

    ID’s Must Be Unique, specifically because it will cause problems in JavaScript and CSS when you try to interact with those elements.

    Login or Signup to reply.
  2. The main issue in your code is because you’re giving all the elements in your loop the same id, which is invalid. id attributes must be unique within the DOM. You should use a class instead to attach the event handlers, then use the this keyword within the event handler to get a reference to the element which raised the event. The latter point means that you need to remove the arrow function and use an anonymous one instead.

    That being said, there’s other issues in your code which need addressing. Firstly the document.ready event handler is not an IIFE. Remove (jQuery) from the end of it. In addition, use data() to retrieve data attributes, not attr(). Lastly, don’t use alert() for debugging as it coerces data types. Use console.log() instead.

    jQuery(function($) {
      edit();
    });
    
    function edit() {
      $(document).on('click', '.edit_btn', (e) => {
        e.preventDefault();
        var aid = $(e.target).data('id');
        console.log(aid);
      });
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <!-- inside your loop ... -->
      <tr>
        <td><a href="#1" class="edit_btn" data-id="1">edit</a></td>
        <td><a href="#1" class="delete_btn" data-id="1">delete</a></td>
      </tr>
      <tr>
        <td><a href="#2" class="edit_btn" data-id="2">edit</a></td>
        <td><a href="#2" class="delete_btn" data-id="2">delete</a></td>
      </tr>
      <tr>
        <td><a href="#3" class="edit_btn" data-id="3">edit</a></td>
        <td><a href="#3" class="delete_btn" data-id="3">delete</a></td>
      </tr>
    </table>

    If you’d prefer to use the arrow function then instead of this you would need to use e.target:

    $(document).on('click', '.edit_btn', (e) => {
      e.preventDefault();
      var aid = $(e.target).data('id');
      console.log(aid);
    });
    
    Login or Signup to reply.
    1. You can’t have multiple elements with same ID. jQuery will always use the first one found.
    2. You can set a class to all your edit/delete buttons and use it to register the click event.
    3. You can use $(this) inside the callback to manipulate only the clicked element

      <td><a class="edit_btn" data-id="<?= $row->id; ?>">edit</a></td>
      <td><a class="delete_btn" data-id="<?= $row->id; ?>">delete</a></td>
      
      $(document).on('click','.edit_btn', function(e) {
          e.preventDefault();
          var aid = $(this).data('id');
          alert(aid);
      });
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search