Reputation: 3
i am in touch with jquery for the first time and ran into this: I am trying to create a dynamic input-form. A click function creates a new list-item with another click function nested into it (to provide a remove function for the clicked item).
When i execute the nested click function it appears to be called the number of instances that have been created of it.
Here is the code (i tried to remove as much as possible, but i am not quite sure where the error is - so i guess i left to much stuff in - sorry).
$("#addIngredient").click(function(e){
e.preventDefault();
var prefix = "form-"
var last = $("#IngredientForm ul li").last().html();
$("#IngredientForm ul").append("<li>"+last+"</li>");
var name = $("#IngredientForm ul li:last input").attr("name");
name = name.replace(prefix,'');
var count = parseInt(name[0]);
count += 1;
$("#IngredientForm ul li:last input").attr("name",prefix+count+"-weight")
$("#IngredientForm ul li:last select").attr("name",prefix+count+"-ingredient")
$("#IngredientForm ul li:last input").attr("id","id_"+prefix+count+"-weight")
$("#IngredientForm ul li:last select").attr("id","id_"+prefix+count+"-ingredient")
$("#id_form-TOTAL_FORMS").val(count+1);
$(".deleteIngredient").click(function(e){
e.preventDefault();
var aktuell = $(this).closest('li');
var formCount;
name = aktuell.children('input').attr("name");
name = name.replace(prefix,'');
counter = name.replace("-weight",'');
formCount = parseInt($("#id_form-TOTAL_FORMS").val());
aktuell.remove();
--formCount;
$("#id_form-TOTAL_FORMS").val(formCount);
for (var i = parseInt(counter); i<formCount; i++){
var newName = "form-"+(i);
$("#id_form-"+(i+1)+"-weight").attr("name",newName+"-weight");
$("#id_form-"+(i+1)+"-ingredient").attr("name",newName+"-ingredient");
}
});
});
Upvotes: 0
Views: 57
Reputation: 8793
Use this format instead
$("#addIngredient").on('click', function() {
$(this).off();
});
Upvotes: 0
Reputation: 780724
As the other answers have noted, the click handler is adding a click handler to every .deleteIngredient
element every time you run it, which adds multiple handlers to all the previous elements.
When you add a new item to the list, you don't have to add a click handler to it. You can use delegation to create a handler one time that will apply to dynamically-added elements:
$("#IngredientForm").on("click", ".deleteIngredient", function(e) {
...
});
See Event binding on dynamically created elements? for more information.
Upvotes: 1
Reputation: 8268
This block
$(".deleteIngredient").click(function(e){...
attaches a clickevent to all .deleteIngredient
elements, also those created before.
You have to put this block outsite the click event of #addIngredient
. You can make the delete event to be attached also to every element added in the future.
$("#addIngredient").click(function(e){
// ...
});
$(document).on("click", ".deleteIngredient", function(e){
// ...
});
Upvotes: 2
Reputation: 413702
Every time that outer "click" event happens, you're adding another "click" handler for the ".deleteIngredient" element(s). The .click
function does not remove previously-assigned event handlers.
You can get rid of old handlers with .unbind
or, preferably with new versions of jQuery, .off
:
$('.deleteIngredient').unbind('click').click(function(event) {
// ...
});
No, the thing is, here I think you probably want to bind to the .deleteIngredient
button that you're adding for the new ingredient. The code you've got — based on the reference to $('.deleteIngredient')
— will affect all of the elements on the page with that class. My guess here is that you're adding a button or something for each <li>
. Thus, what you should probably be doing is finding the button inside the newly-added structure:
$('#IngredientForm ul li:last .deleteIngredient').click(function(event) {
// ...
});
Upvotes: 0