Kaushik Thanki
Kaushik Thanki

Reputation: 3540

Why my plugin fires multipe callback or clicks

I am creating my simple jQuery plugin that can be use to attach for any action's confirmation. But facing very strange issue, It work fine for single element click, But when i am going to click for second element which also bind with my plugin it work fine but it's also fires for previous clicked element as well.

(function ($) {

$.fn.BootConfirm = function (options) {
    // Establish our default settings
    var settings = $.extend({
        message: 'Are you sure about this ?',
        complete: null
    }, options);

    var self = this;
    var cointainer = '\
                    <div class="modal fade" id="confirmBoot" role="dialog" aria-labelledby="confirmDeleteLabel" aria-hidden="true">\
                      <div class="modal-dialog">\
                        <div class="modal-content">\
                          <div class="modal-header">\
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>\
                            <h4 class="modal-title">Confirm action</h4>\
                          </div>\
                          <div class="modal-body">\
                            <p>Are you sure about this ?</p>\
                          </div>\
                          <div class="modal-footer">\
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>\
                            <button type="button" class="btn btn-success btn-ok" id="confirm">Ok</button>\
                          </div>\
                        </div>\
                      </div>\
                    </div>';

    return this.each(function () {
        var self = this;
        $(this).click(function () {
            if (!$('#confirmBoot').length) {
                $('body').append(cointainer);
            }
            if (settings.message) {
                $('#confirmBoot').find('.modal-body').text($(this).attr('data-confirm'));
            }
            $('#confirmBoot').modal({ show: true });

            if ($.isFunction(settings.complete)) {
                $('#confirmBoot').find('.btn-ok').click(function () {                        
                    $.when(settings.complete.call(this, self)).done(function () {
                        $('#confirmBoot').modal("hide"); // Alerts "123"
                    });
                });
            }
        });
    });
}
}(jQuery));

This is my callback function :

function kaushik(myObject) {
ManageAcriveProducts(myObject);
};

and i am calling it by following way

$('a[data-confirm]').BootConfirm({
        complete: kaushik
    });

For more detail check this js fidder Jsfiddle. Can anyone one share possible solution or better way to do this. Or is there any better way to achieve this ?

Upvotes: 0

Views: 63

Answers (1)

Julien Gr&#233;goire
Julien Gr&#233;goire

Reputation: 17144

The problem is that you're assigning a click on your btn-ok on every click event on a bootconfirmed object. And each click is linked to the object that has been clicked, so it ends up in your callback every time you click btn-ok.

One simple fix, though I'm not sure it's the best, is to remove the click on your btn-ok after the action is complete. Like this:

      $.when(settings.complete.call(this, self)).done(function () {
               $('#confirmBoot').modal("hide");
               $('#confirmBoot').find('.btn-ok').off('click');
       });

Working fiddle: http://jsfiddle.net/ywunutyw/

EDIT:

A little improvement on previous solution, it might need some adjustments, since I didn't look into details, but it should give you some ideas. To prevent adding click events and removing them every time user clicks on a button, you can define the click on modal window outside click behavior of each active/inactive button. And on click of active/inactive you define target that will be used in modal confirmation. Like this:

Just before calling behaviors with this.each:

$(document).on('click', '#confirmBoot .btn-ok',
        function (e) {
            if ($.isFunction(settings.complete)) {
                console.log(self)
                $.when(settings.complete.call(this, click_origin)).done(function () {
                    $('#confirmBoot').modal("hide");

                });
            }
            });

Then on the click event of you active/inactive:

click_origin = e.target;

See fiddle: http://jsfiddle.net/ywunutyw/1/

Upvotes: 1

Related Questions