John
John

Reputation: 177

jQuery - click event fires multiple times

I have strange problem with modal widows in ASP.NET MVC. I created a link which is responsible for showing up modal window. The modal window shows up and contains one button - save button. I attached a click eventhandler to this button in order to save the content of the window and then close it. The whole mechanizm looks that way

// this link shows up a modal window 
 @Html.ActionLink("Add", "Add", "Index", null, new { id = "actionLinkAdd" });
and javaScript
$(function () {
        debugger;
        $("#actionLinkAdd").on("click", function (event, action) { // attaching to click event
            debugger;
            event.preventDefault(); //disabling default handler
            var $dialog = $('<div></div>');
            var $url = $(this).attr('href');
            $dialog.empty();
            var $kendoWindow = $dialog.kendoWindow({ //window creating
                height: "200px",
                title: "Dodaj",
                visible: false,
                width: "200px",
                actions: ["Close"],
                content: $url // loading of the window's content (partialView)

            }).data("kendoWindow");
            $kendoWindow.center();
            $kendoWindow.open();

            function onButtonSaveClick(event) { 
                debugger;
                event.preventDefault();
                var $url = $('#target').attr("action");
                $.ajax({
                    url: $url,
                    type: "POST",
                    data: $('#target').serialize(),
                    success: function (response) {
                        $("#btnSave").unbind("click");
                        $kendoWindow.close();
                        $kendoWindow.destroy();
                    },
                    error: function (args) {
                        debugger;
                        $("#btnSave").unbind("click");
                        $kendoWindow.content(args.responseText);                  
                    }
                });
            }
            $('#btnSave').live("click", onButtonSaveClick); // attaching to click event on     save button in the modal window
        });
    });

Everything works almost great.The problem is that function onButtonClick() is fired couple of times. For example if I open modal window two times this function will be invoked also two times. It's quite strange for me because I close modal window,destroy it and even unbind all click event attached to btnSave (I also tried to use on and off function but the behavior of the window is the same). What could be reason of this behavior ?

Upvotes: 3

Views: 4930

Answers (3)

spadelives
spadelives

Reputation: 1628

I found that, in order to have validation on the modal window, I was including a bundle on the modal dialog like this:

@Scripts.Render("~/bundles/jqueryval")

I did this because validation failed when the validation bundle was loaded only on the parent page.

My jqueryval bundle includes three files:

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*", // references two jquery libraries
                        "~/Scripts/jquery.validate*"));

I found that including this bundle was causing the multiple firing problem, presumably because the libraries load up each time the modal dialog is called and remain in memory. When I removed the bundle, the problem went away but validation also failed to occur.

After a lot of experimentation I finally found a resolution; to split up the bundle, moving two of the jquery libraries to the parent page and the third to the model dialog. Specifically...

These two on the parent page:

<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>

and this one on the modal dialog:

<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

With the includes separated, I have no more issues with multiple firings and also preserved validation.

Upvotes: 1

James Ellis-Jones
James Ellis-Jones

Reputation: 3092

Or even better move the line which binds the event:

        }
        $('#btnSave').live("click", onButtonSaveClick);
    });
});

down one line thus:

        }
    });
    $('#btnSave').live("click", onButtonSaveClick);
});

The problem is that you're calling live every time you create a new dialog but failing to unbind it using 'unbind'. But you don't need to, you just bind using live once in the outermost function which is called when the page is ready, and then it will pick up any click on anything with an id = 'btnSave'. Now you shouldn't really be creating multiple dialog windows with elements with the same id in them, you should really set the class to 'btnSave' but that's another story..

Upvotes: 4

ShankarSangoli
ShankarSangoli

Reputation: 69905

To unbind a live event handler use die method. Try this.

$("#btnSave").die("click");

.die() reference: http://api.jquery.com/die/

Upvotes: 2

Related Questions