Liam
Liam

Reputation: 29694

Jquery .on('change') not firing for dynamically added elements

So I've got a page with the following structure

<div class="editCampaignBanner">
    <div>
    <hr>
    <label for="file">Upload a new image</label>
    <input id="file" type="file" name="file" class="valid">
    <label for="NewImageURLs">Link URL (Optional)</label>
    <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
    <hr>
    </div>
</div>

and I've written some jquery thus:

$('div.editCampaignBanner input:file').on('change', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

so when I enter an element into the file it generates a div under the previous one:

    <div class="editCampaignBanner">
        <div>
        <hr>
        <label for="file">Upload a new image</label>
        <input id="file" type="file" name="file" class="valid">
        <label for="NewImageURLs">Link URL (Optional)</label>
        <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
        <hr>
        </div>
        <div>
        <hr>
        <label for="file">Upload a new image</label>
        <input id="file" type="file" name="file" class="valid">
        <label for="NewImageURLs">Link URL (Optional)</label>
        <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
        <hr>
        </div>
    </div>

But now, despite the event being registered using .on() the second file input in the div does not fire the event. What am I missing?

Upvotes: 9

Views: 14136

Answers (4)

Amit Kriplani
Amit Kriplani

Reputation: 682

May be use $.live() jquery method, its deprecated but works for me:

$('div.editCampaignBanner input:file').live('change', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

more info : http://api.jquery.com/live/

if you are reluctant on using the latest (.on()) use it like this :

function fileChanged(ele){
    var value = ele.val();
    var div = ele.parent();
    var html = '<div>'+ div.html() + '</div>';
    if (value.length > 0) {
        div.after(html);
    }
    else if (ele > 1) {
        div.remove();
    }
    $('div.editCampaignBanner').unbind().on('change','input:file', function () {
        fileChanged($(this))
    });
}
$(function(){
    $('div.editCampaignBanner').on('change','input:file', function () {
        fileChanged($(this))
    });
});

Upvotes: 0

Techie
Techie

Reputation: 45124

$(document).delegate("div.editCampaignBanner input:file", "change", function() {
  //code goes here
});


$(document).on('change', 'div.editCampaignBanner input:file', function () {
 //code goes here
});

Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements. As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation. More information on event binding and delegation is in the .on() method.

Differences Between jQuery .bind() vs .live() vs .delegate() vs .on()

Upvotes: 4

nix
nix

Reputation: 3302

try this:

$('div.editCampaignBanner').on('change','input:file', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

Upvotes: 1

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382150

Replace

$('div.editCampaignBanner input:file').on('change', function () {

by

$('div.editCampaignBanner').on('change', 'input:file', function () {

Upvotes: 13

Related Questions