I needed to clear the inputs on a bootstrap modal window whenever it is closed. To do this I added a hidden.bs.model handler.

Why does the event handler hidden.bs.modal fire to clear the inputs before the on click event associated with the "Run" button in the same modal? It prevents me from being able to use the values in the inputs as they are already cleared by the hidden.bs.modal

// BUTTON LOOKUP
$( '.container').on("click", ".btnGetPerson", function() {
    var dlic = queryPersonInputValue.match(/^[a-zA-Z]{2}\d{6}$/);
    console.log('the value of variable dlic is  :' +dlic);        
    // other REST stuff 
});

// RESET LOOKUP MODAL ON CLOSE
$('#queryPersonModal').on('hidden.bs.modal', function() {
    console.log('modal closed');
    $(this)
        .find("input,textarea,select")
        .val('')
        .end()
        .find("input[type=checkbox], input[type=radio]")
        .prop("checked", "")
        .end();

});

console.log('the value of dlic is :' +dlic); always prints null since adding the hidden.bs.modal.

I have added the HTML to a fiddle:

https://jsfiddle.net/bigalnz/gLw8pnx3/1/

1 Answers

2
andreivictor On

It's all about event bubbling and event propagation:

When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors, terminating at the window object.

You have already used this principle when writing the click handler for .btnGetPerson button, using .container element.


Bootstrap Modal Js implements the click handler for the elements that have the data-dismiss attribute in the following way:

this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))

where this.$element is the modal element, and this.hide is the method that hides the modal and triggers the hidden.bs.modal event.


So, when a [data-dismiss="modal"] is clicked, we have the following event sequence:

0: button.btn.btn-primary.btnGetPerson
1: div.modal-footer
2: div.modal-content
3: div.modal-dialog
4: div#queryPersonModal.modal (*)
5: div.container
6: body
7: html
8: document
9: Window 

So the click.dismiss.modal will run only after all the click handlers for .btnGetPerson, .modal-footer, .modal-content, .modal-dialog had run.

Accordingly, all the events handlers attached to the .container element will run after #queryPersonModal.modal events.


So, my solution is to attach the click handler directly to '.btnGetPerson' element:

$(".btnGetPerson").on("click", function() {      
    // ...
});

Fiddle: https://jsfiddle.net/z6ntys7f/23/

Or, if the modal html is inserted into page asynchronously, you can take the following approach: - remove the data-dismiss attribute from the button - add $('#queryPersonModal').modal('hide'); in the click handler:

$(".container").on('click', '.btnGetPerson', function(e) {
   // var dlic = queryPersonInputValue.match(/^[a-zA-Z]{2}\d{6}$/);
   var dlic = $('#query-name').val();
  console.log('the value of variable dlic is  :' +dlic);        
  // other REST stuff 

  $('#queryPersonModal').modal('hide'); 
});

Fiddle: https://jsfiddle.net/z6ntys7f/25/