aanders77
aanders77

Reputation: 630

Jquery event bubbling when .on event is within a nested function

I have this code in the body onload event:

$.each(["#tbl_p2", "#tbl_p5", "#tbl_ukalk"], function(index,value){
    $("tbody tr:not(:last)", value).find("input[type='text']:visible:last").on("blur", this, function(){
        $("tbody tr:last input[type='text']:first", value).focus()
    })
})

The mentioned tables (tbl_p2, tbl_p5 and tbl_ukalk) are all added dynamically at some point and they consists of several lines with several text inputs at each line. The intention of the code is to focus() the first input of the last line whenever the the last input of whichever line is blurred.

It works when applied through the console, but not via onload, so I know it has something to do with bubbling. I've tried to add "document" like this...

$.each(["#tbl_p2", "#tbl_p5", "#tbl_ukalk"], function(index,value){
    $("document tbody tr:not(:last)", value).find("input[type='text']:visible:last").on("blur", this, function(){
        $("tbody tr:last input[type='text']:first", value).focus()
    })
})

...to bubble far enough out, but that won't work neither in console or onload - I'm assuming beacuse "document" isn't part of the given context in $.each().

I've also tried to do $.each(["document #tbl_p2", ...]) but that doesn't work either.

Edit: Added jsfiddle with working code. If the tables were added dynamically, it wouldn't work.

Edit II: Updated jsfiddle with dynamically added table, which serves to show that the event listener doesn't update to the new table element.

Edit III: 100% working jsfiddle, many thanks to @Rob Schmuecker (see accepted answer)

Upvotes: 0

Views: 291

Answers (2)

Rob Schmuecker
Rob Schmuecker

Reputation: 8954

I think this is to do with event delegation since the tables aren't loaded by the time you've called onload?

Have a look here http://api.jquery.com/on/ about delegating your events. You may have to reformat your code slightly to get it to work properly.

Or alternatively call your code only when the tables have actually been loaded into the DOM such as in the success callback of an ajax request or similar.

EDIT: Here is a correct working fiddle http://jsfiddle.net/7UTBQ/3/ and here is the correct working javascript

JS:

$(document).on("blur", "table tr:not(tr:last-child) td:last-child input[type='text']:visible", function (event) {
    console.log('blur');
    $("tr:last input[type='text']:first", $(event.target).parents('table').get(0)).focus();
});

Upvotes: 1

Manwal
Manwal

Reputation: 23816

try this

$.each(["#tbl_p2", "#tbl_p5", "#tbl_ukalk"], function(index,value){
    $("document tbody tr:not(:last) "+value).find("input[type='text']:visible:last").on("blur", this, function(){
        $("tbody tr:last input[type='text']:first "+value).focus()
    })
})

Not tested by my side you can try..

Upvotes: 0

Related Questions