alisongaleon
alisongaleon

Reputation: 153

Double trigger on jquery modal function

I have this code which always doubles the previous function.

var deleteModal = $('.bs-delete-modal-sm');
deleteModal.on('shown.bs.modal', function(event) {
  var button = $(event.relatedTarget); // Button that triggered the modal
  var recipientId = button.data('aishid');

  var confirmBtn = deleteModal.find('.confirmDeleteBtn');
  var parent = button.closest('.year-calendar');
  //console.log(confirmBtn);
  confirmBtn.click(deleteHoliday);

});

function deleteHoliday() {
  $('.textherearea').append('here ');
  deleteModal.modal('hide');
}
<html>

<head>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

</head>

<body>
  <button class="deleteBtn" data-toggle="modal" data-target=".bs-delete-modal-sm" data-aishid="24"><i class="fa fa-trash"></i>
  </button>
  <button class="deleteBtn" data-toggle="modal" data-target=".bs-delete-modal-sm" data-aishid="25"><i class="fa fa-trash"></i>
  </button>
  <div class="modal fade bs-delete-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="myModalLabel">Confirm delete?</h4>
        </div>
        <div class="modal-body">
          Delete this holiday?
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary confirmDeleteBtn">Confirm</button>
        </div>
      </div>
    </div>
  </div>
  <div class='textherearea'></div>
</body>

</html>
It seems that after the modal hides and re launched via the button triggers, the confirm button attached function runs twice as much.

Can someone point me out on how to resolve this and make it run only once.

Thanks.

Upvotes: 0

Views: 405

Answers (1)

hsh
hsh

Reputation: 1855

Adding event handlers in JQuery won't delete or remove existing event handlers, each time you use confirmBtn.click(deleteHoliday);, JQuery adds a click handler to the list of existing handlers and when user clicks on it JQuery triggers all of them one by one so you need to unbind or off existing click events you'v bound to the button before binding new one like this:

confirmBtn.unbind( "click" ); //unbind is deprecated and its better to use .off()
//
confirmBtn.off( "click" );

You can also check if the confirmBtn has any click event assigned or not using this:

 var btnEvents = $._data(confirmBtn[0], 'events');
 if(btnEvents && btnEvents.click)
    console.log("btn has click event");
 else
    console.log("btn hasn't click event");

var deleteModal = $('.bs-delete-modal-sm');
deleteModal.on('shown.bs.modal', function(event) {
  var button = $(event.relatedTarget); // Button that triggered the modal
  var recipientId = button.data('aishid');

  var confirmBtn = deleteModal.find('.confirmDeleteBtn');
  var parent = button.closest('.year-calendar');
  //console.log(confirmBtn);
   var btnEvents = $._data(confirmBtn[0], 'events');
   console.log(btnEvents);
  if(btnEvents && btnEvents.click)
    console.log("btn has click event");
  else
    console.log("btn hasn't click event");
  //confirmBtn.unbind( "click" );
  confirmBtn.off( "click" );
  confirmBtn.click(deleteHoliday);

});

function deleteHoliday() {
  $('.textherearea').append('here ');
  deleteModal.modal('hide');
}
<html>

<head>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

</head>

<body>
  <button class="deleteBtn" data-toggle="modal" data-target=".bs-delete-modal-sm" data-aishid="24"><i class="fa fa-trash"></i>
  </button>
  <button class="deleteBtn" data-toggle="modal" data-target=".bs-delete-modal-sm" data-aishid="25"><i class="fa fa-trash"></i>
  </button>
  <div class="modal fade bs-delete-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="myModalLabel">Confirm delete?</h4>
        </div>
        <div class="modal-body">
          Delete this holiday?
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary confirmDeleteBtn">Confirm</button>
        </div>
      </div>
    </div>
  </div>
  <div class='textherearea'></div>
</body>

</html>

Upvotes: 1

Related Questions