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

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');

Related

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

Dynamically added javascript is not working, but static code works fine?

Here is what I'm doing... I have a textbox that users type something in and click an add icon. This fires some jquery code that adds the item they typed into a span within a "content" div. The generated code has a delete icon that appears on hover and when clicked it should make the span disappear. This works if the code is on the page already (before document load) but if it's dynamically created, it breaks the delete on click functionality.
Here is a JSfiddle so you can see it in action: http://jsfiddle.net/WF32y/
What can I do to fix this? I essentially want to do what happens on here (stackoverflow.com) when you enter tags to a new question.
Use event delegation for dynamically added elements by changing this:
$('a.delete').on('click', function(e) {
Into this:
$(document).on('click', 'a.delete', function(e) {
Fiddle
.on() Direct and delegated events reference
Also, concerning performance, you can attach the handler to a closer ancestor of the dynamically added elements than the document (e.g. a static wrapper element).
You can easily do it with delegate. In your case:
$('#container').delegate('a.delete','click', function(e) {
e.preventDefault();
taskID = $(this).closest('.task')[0].id;
$(this).closest('.task').fadeTo(300, 0, function() {
$(this).animate({
width: 0
}, 200, function() {
$(this).remove();
});
});
});
And by the way FYI:
// jQuery version 1.4.3+
$('#container').delegate('a.delete'...
// jQuery 1.7+
$('#container').on('click', 'a.delete', function(e) {
it is faster and more propery way than:
$(document).on('a.delete'...
or:
$('body').delegate('a.delete'...
or:
$(document).delegate('a.delete'...

Access an element by class using jQuery

I have a table with an ID of InstrumentListGrid. When a row is selected, it sets the class to ui-iggrid-activerow. I want to add a jQuery event on that row for when someone clicks it.
So far I have
$("#InstrumentListGrid tr.ui-iggrid-activerow").click(function (event) {
alert("YAY!");
});
but that isn't firing. How do I bind to an element by class?
since the class is presumably added dynamically you should use .delegate()
$('#InstrumentListGrid').delegate('.ui-iggrid-activerow', 'click', function (e) {
// do stuff.
});
It appears that ui-iggrid-activerow is dynamically added. Use the live() function:
$('#InstrumentListGrid tr.ui-iggrid-activerow').live('click', function() {
alert('YAY!');
});

JQuery ajax and dom issue

I am using JQuery to add a row to a table. Within the row is an element who's click event I am capturing:
$(document).ready(function() {
var newRow = "<tr> ... </tr>";
$('tableName > tbody:last').append(newRow);
$(...).click( function() { // click event on newly inserted elem in the row
alert("click");
});
}
This works great and the alert comes up as expected. BUT when I now add the new row dynamically via an ajax call and parsing the xml, it stops working:
$(document).ready(function() {
getData();
$(...).click( function() { // click event on newly inserted elem in the row
alert("click");
});
function getData() {
$.ajax({
...
success: function(data) {
//parse the xml
$('tableName > tbody:last').append(parsedXml);
}
});
}
The html is correctly added to the DOM, but the click event is no longer captured. Is there some issue with scope or closures going on here?
use
$(...).live('click', function() { // click event on newly inserted elem in the row
alert("click");
});
This keeps the click event running after it has been used
more info
When working with a table, I like to use .delegate() for this. It's very similar to .live(), but lets you set up an event listener on a single parent element, rather than individual handlers on every child element. So whether you have a table of one row or 1000, you still need only one handler.
$('#yourtable').delegate('your_descendant_element','click', function(){
alert("click");
});
You should look into using the live() event handler. It allows you to create an event that matches elements created in the future dynamically, which is what is not happening right now. Another way to fix it would be to move the all to bind down below where you append the new table row, but live() is a much better answer.

Categories