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

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)

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();
});

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..

Related

How to raise an event click, have fields added to Ajax?

I have code that works correctly
$(document).on('click',"a.img,a.imgs",function() {
$(this).next().find('a:first').click();
return false;
});
But when I add new fields ajax ( for example show more), then with them this code does not work, and it's sad
Edited my answer as I misread your code and got everything mixed up.
Here's an explanation from another SO thread that might help you fix the problem:
It's probably not working due to one of:
Not using recent version of jQuery
Not wrapping your code inside of DOM ready
or you are doing something which causes the event not to bubble up to the listener on the document.
$(document).ready(function() {
// This WILL work because we are listening on the 'document',
// for a click on an element with an ID of #test-element
$(document).on("click","#test-element",function() {
alert("click bound to document listening for #test-element");
});
// This will NOT work because there is no '#test-element' ... yet
$("#test-element").on("click",function() {
alert("click bound directly to #test-element");
});
// Create the dynamic element '#test-element'
$('body').append('<div id="test-element">Click mee</div>');
});
$(document).on("click"... not working?

jQuery Toggling next row in dynamically created table with dynamically created button

I have a jQuery dynamically created table that appends data from json file.
one of the rows of the table is a row of buttons that are appended into a row variable that is appended into the table:
var like = $("<a href='index.html'><button class='likeBtn'>like</button></a>");
var comment = $("<a href='index.html'><button class='comBtn'>comment</button></a>");
var toggle = $("<a href='index.html'><button class='togBtn'>show/hide comments</button></a>");
row3.append(like).buttonset();
row3.append(comment).buttonset();
row3.append(toggle).buttonset();
$("#table").append(row3);
now I need to toggle the row below in the table when clicking the toggle button.
this is my onclick function:
$(function(){
alert("in");
$('.togBtn').click(function() {
alert("in2");
$(this).closest('tr').toggle();
});
});
when I put alerts inside the click function I don't see them, I do see alerts from the function that holds the click function. for example- I see "in" but I don't see "in2".
and of course the row is not toggled.
commentRow is the class of the row that needs to be toggled.
I tried lots of options like-
$("#table").closest('.commentRow').toggle();
also with next() , All(), and many others and I can't get it to work!!!
please - your thoughts on this.
All help will be much appreciated!
It's due to the dynamically generated content, try that:
$(document).on('click','.togBtn',function(e) {
alert("in2");
$(this).closest('tr').toggle();
// or return false; // it does both preventDefault & stopPropagation.
});
This is called event delegation. This technique is only used when you have generated dynamic DOM nodes like as you are doing in your code.
So, in this case all the events were bound when page was initially loaded and the elements are generated after page load, due to that browser didn't registered any event for those elements because of unavailablity. In this case event has to be delegated to the static parent node or to the document itself because it is always available.
Syntax for event delegation using .on() method:
$(staticParent).on(event, selector, cb);
With the help of the answers posted here I found a solution that works:
$(document).on('click','.togBtn',function(e) {
alert("in2");
e.preventDefault();
$(this).parents("tr").next().slideToggle();
// or return false; // it does both preventDefault & stopPropagation.
});
Thanks all for your help!

jQuery not inserting attribute into the link

I have a link to slide down a div as follows.But initially this link has no onclick handler, which I am inserting using the jQuery code.
Show Div
Now the following is the jquery code
//id comes from a loop which runs from 1 to 15
$("#Link_"+id).attr('onclick','$(\'#Div_'+id+'\').slideToggle(\'slow\');');
$("#Link_"+id).attr('style','color:white;');
$("#Link_"+id).attr('value','0');
The last two lines are inserting attributes but the first line is not working and also I am not getting any error.I am using jQuery 1.4
EDIT
Now the surprise,I just by luck tried it,
the first line is working in jquery 1.9.Why?
You can't add a click handler like that, try this instead:
$("#Link_"+id).live('click', function(){
$('#Div_'+id+'').slideToggle('slow');
});
Try binding it this way:
$("#Link_"+id).on("click", function () {
$('#Div_'+id+).slideToggle('slow');
});
as you are using jquery 1.4. You would be needing live instead of on
$("#Link_"+id).live( "click", function() {
$('#Div_'+id+).slideToggle('slow');
});
I would recommend using .click() instead.
$("#Link_"+id).click(function(){
$('#Div_'+id).slideToggle('slow');
return false;
});
To answer the edit: jQuery 1.9 checks if you are trying to set an event handler and adds the handler instead of setting an attribute. jQuery 1.4 doesn't have such a check. (I looked at the source)

Why the jQuery remove is adding an extra element in the dropdown?

See this fiddle..
HTML:
<select>
<option>hey1</option>
<option>hey2</option>
<option>hey3</option>
<option>hey4</option>
<option>hey5</option>
</select>
jQuery:
$(document).ready(function () {
$('select').on('click',function(){
$("option:first",this).remove();
$(this).unbind('click');
});
});
When I run the above code in google Chrome(latest version), the first element is removed but it appends an extra element at the bottom. Why is it behaving like that.
Any ideas? pretty unexpected ..
EDIT:
This picture is for the ones who are not able to see any error..
Looks like a rendering bug in Chrome. You can't actually click on the last hey5 and the DOM doesn't actually create a second one. You can get around this via mousedown:
$('select').one('mousedown',function(){
$("option:first",this).remove();
});
jsFiddle example
I'm pretty sure it's a bug, another fix is using focus event :
$('select').on('focus', function(){
$("option:first", this).remove();
$(this).unbind('focus');
});
fiddle: http://jsfiddle.net/F8E7L/

Javascript tr click event with newly created rows (Updating css)

I am very new to web development. I am currently using tablesorter jquery plugin to create a dynamic table, where the user can add and delete rows. I am having trouble with changing the background color of newly created rows upon clicking. It works fine with rows that are hard coded in html. Here is the relevant code:
$(document).ready(
function() {
$('table.tablesorter td').click(
function (event) {
$(this).parent('tr').toggleClass('rowclick');
$(this).parent('tr').siblings().removeClass('rowclick');
});
}
)
rowclick is a CSS class here:
table.tablesorter tbody tr.rowclick td {
background-color: #8dbdd8;
}
I have tried adding the following to my Javascript function that adds a new row:
var createClickHandler =
function(newrow) {
return function(event) {
//alert(newrow.cells[0].childNodes[0].data);
newrow.toggleClass('rowclick');
newrow.siblings().removeClass('rowclick');
};
}
row.onclick = createClickHandler(row);
The alert correctly displays the text in the first column of the row when I click the new row. However, my new rows do not respond to the CSS class. Anyone have any ideas?
I should also mention that I have updated the tablesorter before applying the clickHandler with:
$("#TASKTABLE").trigger("update");
$("#TASKTABLE").trigger("appendCache");
Delegate your clickable td elements like:
$('table.tablesorter').on('click','td', function(){
using .on() from jQuery 1.7:
As of jQuery 1.7, the .on() method provides all functionality required for attaching event >handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), >and .live(). To remove events bound with .on(), see .off(). To attach an event that runs >only once and then removes itself, see .one()
Try this:
$(newrow).toggleClass('rowclick');
$(newrow).siblings().removeClass('rowclick');

Categories