jQuery .on() event doesn't work for dynamically added element
Asked Answered
M

3

15

I'm making a project where a whole div with buttons is being inserted dynamically when user click a button, and inside that div there's a button, which when the user click on it, it does something else, like alerting something for example.

The problem is when i press on that button in the dynamically added div, nothing happens. The event doesn't fire at all.

I tried to add that div inside the HTML and try again, the event worked. So i guess it's because the div is dynamically added.

The added div has a class mainTaskWrapper, and the button has a class checkButton. The event is attached using .on() at the end of script.js file below.

Here's my code :

helper_main_task.js : (that's the object that adds the div, you don't have to read it, as i think it's all about that div being dynamically added, but i'll put it in case you needed to)

var MainUtil = {
    tasksArr : [],
    catArr : ["all"],
    add : function(){       

        var MTLabel = $("#mainTaskInput").val(),  //task label  
            MTCategory = $("#mainCatInput").val(), //task category 
            MTPriority = $("#prioritySlider").slider("value"),  //task priority     
            MTContents = $('<div class="wholeTask">\
                                <div class="mainTaskWrapper clearfix">\
                                    <div class="mainMarker"></div>\
                                    <label class="mainTaskLabel"></label>\
                                    <div class="holder"></div>\
                                    <div class="subTrigger"></div>\
                                    <div class="checkButton"></div>\
                                    <div class="optTrigger"></div>\
                                    <div class="addSubButton"></div>\
                                    <div class="mainOptions">\
                                        <ul>\
                                            <li id="mainInfo">Details</li>\
                                            <li id="mainEdit">Edit</li>\
                                            <li id="mainDelete">Delete</li>\
                                        </ul>\
                                    </div>\
                                </div>\
                            </div>');


        this.tasksArr.push(MTLabel);

        //setting label
        MTContents.find(".mainTaskLabel").text(MTLabel);        

        //setting category  
        if(MTCategory == ""){
            MTCategory = "uncategorized";
        }
        MTContents.attr('data-cat', MTCategory);
        if(this.catArr.indexOf(MTCategory) == -1){
            this.catArr.push(MTCategory);
            $("#categories ul").append("<li>" + MTCategory +"</li>");
        }
        $("#mainCatInput").autocomplete("option", "source",this.catArr);

        //setting priority marker color
        if(MTPriority == 2){ 
            MTContents.find(".mainMarker").css("background-color", "red");
        } else if(MTPriority == 1){
            MTContents.find(".mainMarker").css("background-color", "black");
        } else if(MTPriority == 0){
            MTContents.find(".mainMarker").css("background-color", "blue");
        }       

        MTContents.hide();
        $("#tasksWrapper").prepend(MTContents); 
        MTContents.slideDown(100);

        $("#tasksWrapper").sortable({
            axis: "y",
            scroll: "true",
            scrollSpeed : 10,
            scrollSensitivity: 10,
            handle: $(".holder")            
        });

    }
};

script.js : (the file where the .on() function resides at the bottom)

$(function(){
     $("#addMain, #mainCatInput").on('click keypress', function(evt){       
        if(evt.type == "click" || evt.type =="keypress"){
            if((evt.type =="click" && evt.target.id == "addMain") ||
                (evt.which == 13 && evt.target.id=="mainCatInput")){    
                    MainUtil.add();                                             
            }
        }
    });

    //Here's the event i'm talking about :
    $("div.mainTaskWrapper").on('click', '.checkButton' , function(){
        alert("test text");
    });
});
Margarito answered 30/8, 2012 at 23:30 Comment(3)
I just read the title, did you try out jQuery's .live methodUpwards
@yngum: .live was deprecated in favour of .on.Gondar
@yngum .live is deprecated in favor of .onContain
G
33

It does not look like div.mainTaskWrapper exist.

From the documentation (yes, it is actually bold):

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(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page.

[...]

By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

You might want to bind it to #tasksWrapper instead:

$("#tasksWrapper").on('click', '.checkButton' , function(){
    alert("test text");
});
Gondar answered 30/8, 2012 at 23:33 Comment(0)
C
3

You need to specify a selector with on (as a parameter) to make it behave like the old delegate method. If you don't do that, the event will only be linked to the elements that currenly match div.mainTaskWrapper (which do not exists yet). You need to either re-assign the event after you added the new elements, or add the event to an element that already exists, like #tasksWrapper or the document itself.

See 'Direct and delegate events' on this page.

Contain answered 30/8, 2012 at 23:38 Comment(1)
They are talking about the other event handler: $("div.mainTaskWrapper").on('click', '.checkButton' , ...).Gondar
C
3

I know this is an old post but might be useful for anyone else who comes across...

You could try:

jQuery('body')on.('DOMNodeInserted', '#yourdynamicallyaddeddiv', function () {
//Your button click event
});

Here's a quick example - https://jsfiddle.net/8b0e2auu/

Crapshooter answered 7/10, 2015 at 16:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.