0

When showing bootstrap modal, one can easily retrieve associated data using code such as

$('#myModal').on('show.bs.modal', function (e) {
   var id = $(e.relatedTarget).data('id'); 
   alert(id);
}

Is it possible to the same when closing bootstrap modal?
Especially when closed by specific button (i.e. confirm button, not either of the cancel buttons)? The relatedTarget does not seem to be available from any buttons inside the modal nor in the hidden.bs.modal event.
In the following playground data-id attribute value should be displayed below delete buttons when modal's "yes" is clicked in similar manner data-id is displayed the modal body:

$(document).ready(function () {
  $('#deleteModal').on('show.bs.modal', function (e) {
      $('#testOutput,#testOutput2').text('');
       var id = $(e.relatedTarget).data('id'); 
    $('#deleteId').text(id || 'id retrieval failed');
  });
  
  $('#deleteModal').on('hidden.bs.modal', function (e) {
      var id = $(e.relatedTarget).data('id'); //does not work
      $('#testOutput2').text(id || '"hidden.bs.modal" id retrieval failed');
  });  
  
  $('#confirmDeleteBtn').click(function (e) {
    var id = $(e.relatedTarget).data('id');  //does not work
    //var id = $(this).closest('.modal').data('id'); //doesnt work neither
    $('#testOutput').text(id || '"btn.close .modal" id retrieval failed');
  });
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div class="col offset-3">
  <div class="d-flex">
    <button class="mt-4 btn btn-primary" data-toggle="modal" data-target="#deleteModal" data-id="42">delete record 1</button>
    <button class="mt-4 btn btn-primary" data-toggle="modal" data-target="#deleteModal" data-id="123">delete record 2</button>
  </div>
  <h5 class="mt-4 text-danger" id="testOutput"></h5>
  <h5 class="text-danger" id="testOutput2"></h5>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="deleteModalTitle">Confirm delete</h5>
            <button type="button" class="close" data-dismiss="modal">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <p>Delete record <span class="font-weight-bold text-danger" id='deleteId'></span>?</p>
          </div>
          <div class="modal-footer">
            <button class="btn btn-primary" type="button" id="confirmDeleteBtn" data-dismiss="modal">Yes</button>
            <button class="btn btn-outline-secondary" id="cancelDeleteBtn"type="button" data-dismiss="modal">Cancel</button>
          </div>
        </div>
    </div>
</div>

please note the id of opening button is not constant, i.e. there are many delete buttons capable of opening single dialog.

freedomn-m
  • 27,664
  • 8
  • 35
  • 57
wondra
  • 3,271
  • 3
  • 29
  • 48
  • @freedomn-m have to admit is could be viewed ambiguos, however getting value of attribute from a html element would be trivial so I am confident most if not all will understand understand it as indetended. Anyhow, could you suggest non-ambiguous title? – wondra Apr 08 '19 at 12:03
  • 1
    @freedomn-m ah, the main confusion here is about the Bootstrap's [modal data-passing pattern](https://stackoverflow.com/a/25060114/3096657). So instead of "pass data->onopen->get data" I d like "pass data->open->on closing->get data" not sure how to include it in the title though. It is not related to the closing button in any matter (well, except when its closed, I need the previously passed data). – wondra Apr 08 '19 at 13:32

2 Answers2

1

You can set data-id attribute to a hidden input inside your modal and take id from there only. Try below code-

$(document).ready(function () {
  $('#deleteModal').on('show.bs.modal', function (e) {
      $('#testOutput,#testOutput2').text('');
       var id = $(e.relatedTarget).data('id'); 
       $('input.delete-btn-id').val(id);
    $('#deleteId').text(id || 'id retrieval failed');
  });
  
  $('#deleteModal').on('hidden.bs.modal', function (e) {
      var id = $('input.delete-btn-id').val(); //it's working now
      $('#testOutput2').text(id || '"hidden.bs.modal" id retrieval failed');
  });  
  
  $('#confirmDeleteBtn').click(function (e) {
    var id = $('input.delete-btn-id').val();  //it's working now
    $('#testOutput').text(id || '"btn.close .modal" id retrieval failed');
  });
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div class="col offset-3">
  <div class="d-flex">
    <button class="mt-4 btn btn-primary" data-toggle="modal" data-target="#deleteModal" data-id="42">delete record 1</button>
    <button class="mt-4 btn btn-primary" data-toggle="modal" data-target="#deleteModal" data-id="123">delete record 2</button>
  </div>
  <h5 class="mt-4 text-danger" id="testOutput"></h5>
  <h5 class="text-danger" id="testOutput2"></h5>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="deleteModalTitle">Confirm delete</h5>
            <button type="button" class="close" data-dismiss="modal">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <p>Delete record <span class="font-weight-bold text-danger" id='deleteId'></span>?</p>
            <input type="hidden" val="" class="delete-btn-id"/>
          </div>
          <div class="modal-footer">
            <button class="btn btn-primary" type="button" id="confirmDeleteBtn" data-dismiss="modal">Yes</button>
            <button class="btn btn-outline-secondary" id="cancelDeleteBtn"type="button" data-dismiss="modal">Cancel</button>
          </div>
        </div>
    </div>
</div>
Shubham Baranwal
  • 2,492
  • 3
  • 14
  • 26
0

You can save Id's value into a input hidden when the modal show

...
<div class="modal-body">
   <p>Delete record <span class="font-weight-bold text-danger" id='deleteId'></span>?</p>
   <input type='hidden' id='deleteIdInput' />
</div>
...

$('#deleteModal').on('show.bs.modal', function (e) {
  $('#testOutput,#testOutput2').text('');
  var id = $(e.relatedTarget).data('id'); 
  $('#deleteId').text(id || 'id retrieval failed');
  $('#deleteIdInput').val(id);
});

$('#deleteModal').on('hide.bs.modal', function (e) {
  var id = $('#deleteIdInput').val(); //does not work
  $('#testOutput2').text(id || '"hidden.bs.modal" id retrieval failed');
});  

This is a demo: https://jsbin.com/caqubagobu/

Ryan Nghiem
  • 2,417
  • 2
  • 18
  • 28