Reputation: 818
This is a odd issue and i have searched for an answer but i could not find one that suited my code.
EDIT: This issue happens on a heavy Ajax page, where the page is not refreshed and the Modal are being reused.
Please note my Javascript is a little weak so i am probably approaching this issue wrong
I have found similar issues here and here
Both describe the issue i am having but i just update the calling view on hidden. i don't bind to a button event.
I have multiple Modals defined
<div id="modal_small" class="modal hide fade in">
</div>
<div id="modal_large" class="modal hide fade in">
</div>
I reuse these modals. So the modal_large is displaying a Create Form one second and next its showing a list of images you can select from.
I render my modals using the following script passing in the view to be shown in each instance
function show_modal_large(href) {
$.get(href, function (data) {
$('#modal_large').html(data);
$('#modal_large').modal('show');
});
};
My Goal here is to reuse these modals. and this is where the problem lies i believe
In the "$(document).ready" of the view which is going to display the modal i call this script to bind to the modals 'hidden' event
$('#modal_large').on('hidden', function () {
// Make Ajax Call - THIS WORKS
});
So imaging you have a list on a view showing your selected images. you then open up a modal and select more images. On Hidden i Update the the selected images on the calling form.
Every thing works fine.
The Issue:
The first time i open the modal and close it the 'on hidden' event is fired once. the second time i open and close the modal the 'on hidden' event is call twice, third time three calls and so on. If i go off and use the modal for something else with a different 'hidden' event the hidden event is call four times for the NEW hidden event, and Four times for the old hidden event. After a short while my system just dies with all the ajax calls.
Am i missing something? How should i structure my Code so this does not happen?
Upvotes: 10
Views: 8966
Reputation: 176
You can also use .one instead of .on and the event you are binding will only ever fire once.
Upvotes: 6
Reputation: 818
Ok Figured this out... well kind of. Hope this code is of use to someone else.
As i was binding to the 'hidden' event of the modal, each time it was created i was just adding another binding and another call out to all of the previous binds also.
So to over come this i got rid of the old modal declarations
<div id="modal_small" class="modal hide fade in">
</div>
<div id="modal_large" class="modal hide fade in">
</div>
and instead of them i dynamically create the modals as i need them like so and passing in a call back for the 'hidden' event
function show_modal_large(href, callback) {
// create guid to name of this Modal
var randomNum = guid();
// create element with guid id
var elementName = '#' + randomNum.toString();
$('body').append("<div id=" + randomNum + " class='modal hide fade in'></div>");
// create Modal and show
$.get(href, function (data) {
$(elementName).html(data);
// register call back to 'hidden' event
$(elementName).on('hidden', function () {
callback();
// clean up after hidden
$(elementName).unbind();
$(elementName).remove();
});
$(elementName).modal('show');
});
};
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
function guid() {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
I got the Guid creation from Stackoverflow question here
This works great for me. And solves MY the issue.
Upvotes: 6