2

I'm creating a dynamic menu where I can add and remove a new form.

<input type="button" value="generate form" id="test"/>
<div id="form1"></div>

<script>
$(document).ready(function() {
    $("#test").click(function() {    
        $("#form1").append("<select id='score-attempt'><option value='penalty'>penalty</option></select><input type='button' value='remove' id='remove'/><br>");
    }); 

    $("#form1 #remove").click(function() {    
        alert($(this).index());
    });
});

The problem is that clicking on remove never triggers the alert box.

Thanks

0x499602D2
  • 87,005
  • 36
  • 149
  • 233
user3083672
  • 197
  • 11

2 Answers2

6

The problem is that the element is added later and doesn't exist when the dom is loaded. Therefore the click event has to be delegated from an already existing element, e.g. like this:

$(document).on("click", "#remove", function(){
  alert($(this).index() );
});

Instead of $(document) every other static parent element can be used for event delegation, just as example.

Update for the comments: as mentioned, $(document) only as example. I'd also prefer to use $("#form1") here like mithunsatheesh suggested.

And for reference: https://api.jquery.com/on/#on-events-selector-data-handler, section "Direct and delegated events":

"Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()."

Update for the correct index: you'll get the correct index using e.g.

$("#form1").on("click", ".remove", function(){    
    alert($(".remove").index($(this)));
});

with the adjustment to use remove as class instead of id for the remove-button. IDs have to be unique, so classes are a better solution. index() starts counting with 0, so you'll get 0 for the first one.

As working example: Fiddle

matthias_h
  • 11,162
  • 9
  • 19
  • 38
  • 2
    `$("#form1").on("click","#remove",function() {` would be better – Mithun Satheesh Oct 05 '14 at 16:03
  • 3
    He could also attach the event when he creates `#remove` – George Mauer Oct 05 '14 at 16:04
  • @GeorgeMauer : wouldn't that be better? rather than checking the click target each time a click happens on the document? :) – Mithun Satheesh Oct 05 '14 at 16:06
  • this works - thanks! the index value on the alert seems to be wrong - each one increases by three rather than one – user3083672 Oct 05 '14 at 16:09
  • @user3083672 Glad that I was able to help you, and just updated my answer for the index value issue. – matthias_h Oct 05 '14 at 16:30
  • @mithunsatheesh I haven't measured anything but I very much doubt it. The event has to bubble to the document anyways and will get checked at every level for callbacks. Therefore the most you would be saving is a few `if` statements which are likely to not even require a round trip to memory (which in itself is literally lightning fast). In other words, the difference in terms of speed would be negligible, I would go with whatever one communicated best your intention to someone reading the code. – George Mauer Oct 05 '14 at 20:10
3

You need to add an event handler on your #form1 input with #remove.

Look here, here and here.

Here is the working jsfiddle for you.

Community
  • 1
  • 1
Nimitz E.
  • 85
  • 1
  • 10