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!
Related
I am trying to target a class called 'horizontal-video' in a div within an AEM component and if the author has clicked a checkbox that has an ID of 'coral-id-540' I want to add a second class called 'flipped' to the div. Here is the code I wrote that isn't working. Could someone help me figure out why it's not working? The console does not show errors.
var x = document.getElementsByClassName("horizontal-video");
$('#coral-id-540').change(function(){
if($(this).is(":checked")) {
$(this).addClass("flipped");
} else {
$(this).removeClass("flipped");
}
});
It's quite possible you're not waiting for the DOM to completely load, (or at least have this bit of code below the element in question on the page during page load)
Is your code wrapped in $(document).ready(function(){ //your code });?
Also, be aware that any element that is dynamically added to the page by JavaScript/jQuery after page load will not have a listener attached using the method you're using.
To allow dynamically added elements to be included in your listener, you should target an ancestor node and add the listener to that node. In plain English: attach the listener to a "higher up" element. The safest (although slowest) node being document itself, but it's better to target something closer:
$(document).ready(function () {
var $horizontalVideo = $(".horizontal-video"); //You're using jQuery - why not use it here? Also, I always name jQuery objects with a `$` in front as a shorthand to know it's wrapped in a jQuery object. Plus, a more descriptive name will help you immensely.
//replace parent-of-coral with the ID of a parent element that you know exists on DOM ready:
$("#parent-of-coral").on("change", "#coral-id-540", function (e) { //get used to using "e" as the event variable for preventing default / stopping propagation / etc
$this = $(this); //cache $(this) reference rather than creating another jQuery object each time you use it
if ($this.is(":checked")) {
$this.addClass("flipped");
} else {
$this.removeClass("flipped");
}
});
});
I have a table with some images, when the Ajax is called it removes the previous table and returns another table with new images.
$("img").click(function(){
$.post("gallery.php", function(data){
$("#left-gallery, #right-gallery").html("").append(data);
});
});
This is how I get the information from the php file.
The problem is that the new elements does not trigger the click events that the previous ones use to.
If I clicked on an image in the table it should replace another image on the page outside the table.
$("#left-gallery img").click(function(){
$("#left-gallery td").removeClass("highlighted");
var source = $(this).attr("src");
$("#image1-image").attr("src", source); //replaces a big image outside the table
$(this).parents("td").addClass("highlighted");
});
The table images are nested like :
<tr>
<td>
<a href = "image.jpg">
<img src = "image.jpg">
Image
</a>
</td>
</tr>
Even preventing the default behaviour does not work.
$("td a").click(function(e){
e.preventDefault();
});
The javascript is after the <body> and is internal. I do not know how to get the click events or any to work on the returned table and any help would be appreciated.
Thank you.
use delegation because you are dynamically modifying the DOM
$('#left-gallery').on('click','img',function(){
// your code here
})
By doing this, you attach the event handler to the #left-gallery element = which is static. It will then listen for click events from descendant images and handle them as they bubble up
Depending on which version of jQuery you are using
$('element').live('event',function({ code here..})); // jQuery 1.3+
$('staticparent').delegate('element', 'event', function(){ code here..}); // jQuery 1.4.3+
$('staticparent').on('event', 'element', function(){ code here.. }); // jQuery 1.7+
You were doing
$("#left-gallery img").click(function(){
Which binds the event handlers to the images.. The images no longer exist after you modified the dom.. and you never binding event handlers to the newly added images so thats why the clicking didn't do anything
I am adding the form my current list in a div box at the bottom of the table.
I am appending the div box when someone clicks on add button.
But when i click add button multiple times , then many div boxes are appended.
Is there any way that no matter how many times I click the button, only one instance gets append to div box.
This is my code
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
attach your listener using .one().
$("button").one('click', function(){
// Your code
});
Read more: http://api.jquery.com/one
This is under the assumption that you're using jQuery 1.7+
One simple solution would be having a boolean flag that you can toggle once your button is clicked. Additionally, there is actually a jQuery function that provides this exact functionality.
It's called one() -
Attach a handler to an event for the elements. The handler is executed
at most once per element.
So your code would look something like this -
$("#someTrigger").one('click', function(){
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
});
The boolean method is also very simple -
var wasClicked = false;
$("#someTrigger").on('click', function(){
if (wasClicked == false){
// append your form
wasClicked = true;
}
});
Reference -
one()
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');
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.