Search code examples
jquerymodal-dialogcancellationconfirmation

How to avoid multiple delete when clicking on a Cancellation button


I have a list of records with on every row a red cross to delete this record. The deleting is going OK but I notice some unwanted behaviour within the confirmation modal

When I click on a red cross to delete the record ID 1 and I change my mind so I click on the Cancellation button. But when I want to delete record 2 and I click on the Confirmation button, both record 1 and 2 are deleted but I only want to delete record 2.

Any ideas what to do to prevent that I delete 2 records when I previously clicked before the confirmation button on the Cancellation button in the modal?

$(document).on("click", ".delete_item", function(e) {
  e.preventDefault();
  var user_id = $(this).attr('data-user_id');
  var text_modal = "Are you sure?";
  $('.modal-body').text(text_modal);
  $('#modal-delete').modal('show');

  $('.confirmation').on('click', function() {
    $.ajax({
      type: 'GET',
      url: 'delete.php',
      data: {
        'user_id': user_id
      },
      success: function(html) { // Removing entire row
        $('.ui-sortable li[data-itemid="' + user_id + '"]').remove();
        location.reload();
      }
    });
  });

  $('.cancellation').on('click', function() {
    // Something to prevent double deleting
  });
});

Solution

  • The problem is because you're nesting the event handlers. This means that although you cancel the modal for the first delete, the events are still bound to it. Hence the next time you delete a row all previously opened modals will delete their related rows too.

    To fix this use separate delegated event handlers. You can relate them to the rows using data attributes, like this:

    $(document).on("click", ".delete_item", function(e) {
      e.preventDefault();
      var user_id = $(this).data('user_id');
      $('.confirmation, .cancellation').data('user_id', user_id);
      $('.modal-body').text("Are you sure?");
      $('#modal-delete').modal('show');
    });
    
    $(document).on("click", '.confirmation', function() {
      let user_id = $(this).data('user_id');
      $.ajax({
        type: 'GET',
        url: 'delete.php',
        data: { user_id: user_id },
        success: function(html) { // Removing entire row
          $('.ui-sortable li[data-itemid="' + user_id + '"]').remove();
          location.reload();
        }
      });
    });
    
    $(document).on("click", '.cancellation', function() {
      let user_id = $(this).data('user_id');
      // do something...
    });
    

    There's a couple of other things to note here. Firstly use data() to get/set data attributes, not attr(). Secondly, it would make more sense for the call to delete.php to use the DELETE HTTP verb. Lastly, if you're going to call location.reload() after an AJAX call, then the entire point of the AJAX call is redundant. I'd suggest not doing that.