20

I have made a fiddle illustrating the issue I am facing at the moment. So every time I close and open a modal, shown.bs.modal also fires multiple times. In this fiddle, every time you close and open a modal, number of alerts also increases (when it's supposed to trigger only once). http://jsfiddle.net/j36h2/1/

function openTestModal(){
    $('#testModal').modal({
        keyboard: false,
        backdrop: 'static'
    });

    $('#testModal').on('shown.bs.modal', function (e) {
        alert('');
    });
}

$('.testButton').click(function(){
    openTestModal();
});
BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105
pewpewlasers
  • 3,025
  • 4
  • 31
  • 58

7 Answers7

38

or you can try this :

$('#testModal').on('shown.bs.modal', function (e) {
 alert('');
 $(this).off('shown.bs.modal');
});
ilan weissberg
  • 658
  • 1
  • 7
  • 13
27

The accepted answer from @Put12co22mer2 is correct. However, there are times when you want to rebind the event when opening the modal. Let's say you got some options that should be used.

function openTestModal(options){
    $('#testModal').modal({
        keyboard: false,
        backdrop: 'static'
    });

    $('#testModal').one('shown.bs.modal', function (e) {
        // do something with options
        alert(options.foo);
    });
}

$('.testButton').click(function(){
    openTestModal({ foo: bar});
});

Then you can use one instead of on. The result will be the same as unbinding, but a bit cleaner in my opinion.

http://api.jquery.com/one/

The .one() method is identical to .on(), except that the handler is unbound after its first invocation

smoksnes
  • 10,509
  • 4
  • 49
  • 74
  • 1
    using one() was a cleaner solution for me than on()+off(), as my event binder is in a method that is called recursively. – devRyan Oct 02 '17 at 20:10
18

You need to extract your alert function out from your click event :

http://jsfiddle.net/SyCNj/2/

extract :

function openTestModal(){
    $('#testModal').modal({
        keyboard: false,
        backdrop: 'static'
    });
}

$('#testModal').on('shown.bs.modal', function (e) {
   alert('');
});

$('.testButton').click(function(){
    openTestModal();
});
pewpewlasers
  • 3,025
  • 4
  • 31
  • 58
BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105
  • 1
    There is also the jquery off function to do this, but it's just a bandage, your problem is well here, where your alert function is written.... – BENARD Patrick Jun 08 '17 at 14:26
  • Why is it a bandage? its an available function, why not use it? – Mfoo Oct 30 '17 at 13:58
7

The function below is used for all the dialogs in my application.

It gets called each time with a different callback to execute. The easiest solution for me is simply to remove the event handler before adding a new one.

function messageBox(action,...) {               
    $("#modal-btn-ok").off("click");
    $("#modal-btn-ok").on("click", function(e) {
        action(e);
    }); 
pasx
  • 2,718
  • 1
  • 34
  • 26
4

That's because your are attaching several event handlers for the event, at first click you are listening once, on the second click twice and so on, listen to the event outside the context of openTestModal function.

Ram
  • 143,282
  • 16
  • 168
  • 197
0

Define variable and set it's value to 1; like:

function openTestModal(){
                $('#testModal').modal({
                    keyboard: false,
                    backdrop: 'static'
                });
               var e=1;
                $('#testModal').on('shown.bs.modal', function (e) {
                    alert('');
                    e=0;
                });
            }
Priya jain
  • 753
  • 2
  • 5
  • 15
0

You can try as following: (Bootstrap v3.3.6)

$('#dialog')
.modal({show: false})
.on('hide.bs.modal', function () {
    //..................
}).on('shown.bs.modal', function (event) {
    //..................                  
}).on('hidden.bs.modal', function () {
    $("#dialog").off();
});
$('#dialog').modal('show');
Maksym Kalin
  • 1,693
  • 16
  • 18