Events not working in dynamically added content with jQuery

I’m using bootstrap and loading a form into a modal. When a certain button is clicked it loads an extra field into the form. I’m using popovers for instructions on how to fill out each field in the form. This works for every field except the field that is dynamically added. Here is the code:

$("button#select-field").on("click", function() {
	$('div#db-alias').after('<div class="control-group" id="select-list"><label class="control-label" rel="tooltip" data-title="Instructions" data-content="Add the options for a drop down list. Each option should be separated by a comma (no spaces between options).">Select List Options</label><div class="controls"><input class="field_add" type="text" name="field_add" placeholder="Select List Options"><p class="help-block">Separate values with a comma.</p></div></div>');
});

I have tried .delegate, .live, and .on for creating this field. The popovers work in the modal just fine on all the other form elements and this field is added fine, I just can’t get the popover to work. Any ideas?

The way to handle dynamically added content, is to attach the event to the document and target the event and selector that you require.

For example:


$(document).on('change', 'input.field_add', function () {
    ...
});

Thanks. I tried your suggestion but I don’t think I quite understand how I’m supposed to implement it. I was able to get it to work by adding $(“[rel=popover]”).popover(); in the function. Seems like there should be a better way of doing it rather than repeating that code but I don’t know how.

That’s where the this keyword becomes useful.

jQuery sets the context of the function to the element which triggered the event, so you can use the the this keyword to refer to that element.
In fact, the documentation page for jQuery’s .on() method shows [url=“http://api.jquery.com/on/#entry-examples”]examples, of which the first one demonstrates the this keyword being used.

I’m still quite new to jQuery so forgive me for being thick. I understand the use of the “this” keyword. Here is my revised code:

$(document).on("click", "button#select-field", function() {
    $('div#db-alias').after('<div class="control-group" id="select-list"><label class="control-label" rel="popover" data-title="Instructions" data-content="Add the options for a drop down list. Each option should be separated by a comma (no spaces between options).">Select List Options</label><div class="controls"><input class="field_add" type="text" name="field_add" placeholder="Select List Options"><p class="help-block">Separate values with a comma.</p></div></div>');
    $("[rel=popover]").popover();
});

So for the popover I could have done:

$(this).popover();

But what I don’t understand is why I have to do that at all. It has already been done on the page for the other elements that were loaded with the page. I continually have problems with getting dynamically added elements to work with any existing events. From everything I read it should work by using .on but it doesn’t and I have to instantiate it on element like I did above with the popover. Does that makes sense?

When an event is assigned, it’s only assigned to elements that currently exist on the page. If you later on other elements, there is nothing watching that watches for those elements too allow them to be used as well.

That is why you need something sitting at the document level which is aware of the event and the elements you want to apply it to, so that it can watch for any new elements that match and apply that event to them as well.