user2739275
user2739275

Reputation:

jQuery events for DOM which are inserted to the page after document.ready event

I have written a code to select categories, it works for parent categories but does not work for child categories.

Scenario: The parent cats are a list of DOM elements which are loaded by the page load, but when I click on one of them it makes an ajax request and retrieve the list of its children and then renders them in the page. In this way, a new list of DOMs are clicked, now the following javascript code is responsible to attach click event to the generated child cats. However, it does not work, no console error not anything else, as if there is no JS at all.

//***** SELECTING CHILD CATEGORIES *****/
            var child_cat = $('.new-child-item');
            child_cat.click(function(){alert("AAA");});
            child_cat.on('click', function(){
                console.log("Very Fine");
                if($(this).hasClass('active-child'))
                {
                    $(this).addClass('new-child-item');
                    $(this).addClass('inactive-child');
                    $(this).removeClass('active-child');    
                }
                else
                {
                    $(this).addClass('new-child-item-active');
                    $(this).addClass('active-child');
                    $(this).removeClass('inactive-child');                      
                }
            });         
            //**** SELECTING CHILD CATEGORIES ***/

And here is the generated child cats when the user clicks on its parent:

<div style="display: block;" class="new-item-cats-list-holder clearfix"><div class="inactive-child new-child-item" id="5">
                نرم افزار       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="6">
                سخت افزار       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="7">
                ICDL       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="8">
                شبکه       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="9">
                برنامه نویسی       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="10">
                طراحی       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="11">
                اینترنت       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="12">
                طراحی سایت       
                </div><label class="new-item-side-label"></label><div class="inactive-child new-child-item" id="13">
                تایپ       
                </div><label class="new-item-side-label"></label></div>

Upvotes: 1

Views: 160

Answers (2)

ka.tee.jean
ka.tee.jean

Reputation: 197

The 'click' method sets events for objects that are created when the page loads. To add events to objects that have not been created yet you should use the 'delegate' method (http://api.jquery.com/delegate/)

Basic example here: http://jsfiddle.net/ka_tee_jean/N9EJS/

// initial event on category
$('.cat').on('click',function() {
    $(this).after("<br><span class='new-child-item'>I'm a sub cat</span>");
});

// This won't work cause there are no new-child-items yet
$('.new-child-item').on('click',function() {
    alert("I will never fire");
});

// tell jQuery that this event needs to fire on 
// existing and also on new instances of class new-child-item
// when they are created
$('body').delegate('.new-child-item','click',function() {
    alert("I will fire");
});

Upvotes: 0

Adil
Adil

Reputation: 148180

You need event delegation for dynamically added elements. Use other version of on() for event delegation.

$(document).on('click', '.new-child-item', function(){
    console.log("Very Fine");
    if($(this).hasClass('active-child'))
    {
        $(this).addClass('new-child-item');
        $(this).addClass('inactive-child');
        $(this).removeClass('active-child');    
    }
    else
    {
        $(this).addClass('new-child-item-active');
        $(this).addClass('active-child');
        $(this).removeClass('inactive-child');                      
    }
});         

You have to delegate event to static parent of dynamically added element which is present at the time the event binding code is executed or you can delegate to document/body.

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. 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, jQuery doc

Upvotes: 2

Related Questions