Javascript not executing on elements after ajax request - javascript

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

Related

Click event doesn't fire when parsing external html

I have a project where I need to load html from an external file and add it to an existing div element.
It works great, except that the .click() events never fire when clicking on the desired icon in the generated html.
Code that loads the html:
$.each(data, function (index, review) {
let html = $.parseHTML($.trim(review));
$(html).appendTo($items);
});
Root element of the loaded html is a class named "lc-rating-wrap".
The js that doesn't fire on click:
$(".lc-rating-wrap > .vote-wrap > .do-vote-wrap > .icon").click(function () {
//doStuff
});
I guess it has something to do with that the elements isnt there when I load the js file?
Am I using parseHTML() correctly?
Your content is dynamic, but your event is binded only for existing elements. Change it to be $(static).on(event, dynamic, callback):
$(document).on('click', ".lc-rating-wrap > .vote-wrap > .do-vote-wrap > .icon", function () {
//doStuff
});
Please use delegate instead click.
$( "#parent" ).delegate( ".icon", "click", function() {
//dostuff
});
Parent is a element which you using to generate your elements (inside).
So it cannot be generated dynamicaly.
use jquery click event delegation. see https://learn.jquery.com/events/event-delegation/
Bind event to an parent element already found in your page when js is binding click event. Use .on("click", "your selector", function(){})

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!

DataTable can't get id element after page change

I am trying to make ajax call on focus for every text input, I can make is in first page( when document ready) but when I change page , javascript can't parse inputs because it wasn't created when document is ready. How can I fix it ?
jQuery(document).ready( function(){
jQuery('[id^=urun_sirasi-]').focus(function(){
event.preventDefault();
var urun_sirasi=jQuery(this).data('sira');
console.log(urun_sirasi);
jQuery('#urun_sirasi-'+urun_sirasi).bind('keyup',function(e)
{
console.log(jQuery("#urun_sirasi-"+urun_sirasi).val());
jQuery.ajax({
url:'../ajax.php',
data:'process=siralama&urun_id='+urun_sirasi+'&urun_sirasi='+jQuery.trim(jQuery("#urun_sirasi-"+urun_sirasi).val()),
success:function(e){
// e -> 1 ve ya0 geliyor.
console.log(e);
}
});
});
});
});
Thanks for your help.
This seems to a very common problem in the jQuery section. See the docs for .on() at http://api.jquery.com/on/, specifically the section about delegated events:
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
I use the following syntax in the doc ready that will create events for all future items with the "expand" class, should be able to be adjusted for you
$(document).on('click',"#myTable .expand", function(){
so yours should be something like this (maybe give your items a class rather than having an event to each element selector)
$(document).on('keyup',"#yourTable .urun_sirasi-key", function(){

jQuery won't bind click to underscore template using .on() for items added via function

I'm using underscore to create some elements and appending them to a div with jQuery.
At the bottom of the page I'm using jQuery's .on() to respond to clicks on the elements.
$('.pickup').on('click',
function(e) {
alert("hello");
}
);
Via some user interaction (in Google maps), I've got to add more elements to the div and want them to respond to clicks as well. For some reason they do not. I've pared it all down on jsfiddle:
http://jsfiddle.net/thunderrabbit/3GvPX/
When the page loads, note that clicking on the lines in output will alert('hello') via jQuery.
But click the [add] button and the new lines do not respond to clicks.
My HTML
<div id="unit_2225" class="pickup">
<span>Click me; I was here first</span>
</div>
<script type="text/template" id="unit-template">
<div class="unit-item">
<span class="pickup">
<span>click us (<%= unit_id %>) via underscore</span>
</span>
</div>
</script>
<div id="divID">
</div>
<button>add</button>
My Javascript
var addUnitToDiv = function(key,val) {
console.log(val);
var template = _.template($('#unit-template').html(),val);
$('#divID').append(template);
}
var unit_ids = [{unit_id:'hello'},
{unit_id:'click'},
{unit_id:'us'},
{unit_id:'too'},
{unit_id:112}];
$.each(unit_ids, addUnitToDiv);
var unit_pids = [{unit_id:'we'},
{unit_id:'wont'},
{unit_id:'respond'},
{unit_id:'to'},
{unit_id:'clicks'},
{unit_id:358}];
createMore = function() {
$.each(unit_pids, addUnitToDiv);
}
$('.pickup').on('click','span',function() {
alert("hello");
});
$('button').click(createMore);
I found a similarly worded question but couldn't figure out how to apply its answer here.
Instead of binding events directly to the elements, bind one event to their container element, and delegate it:
$("#divID").on("click", ".pickup", function () {
// Your event handler code
});
DEMO: http://jsfiddle.net/3GvPX/3/
In this case, the event handler is only executed for elements inside of the container #divID that have the class "pickup".
And in your scenario, the elements are being added to the element with an id of "divID". Thus, where the two selectors came from.
This is handy because, as you've found out, dynamically adding elements doesn't magically bind event handlers; event handlers bound normally with .on() are only executed (bound) on those present at the time of binding.
It could even help if you change the delegated selector to "span.pickup" (if you know the elements will always be a <span> like in your template), so that the DOM is filtered by the tag name first.
Reference:
http://api.jquery.com/on/#direct-and-delegated-events
Working demo http://jsfiddle.net/u2KjJ/
http://api.jquery.com/on/
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. You can attach the handler on the document level.
Hope it fits the need, :)
code try the code changed below
$(document).on('click','.pickup',function() {
alert("hello");
});

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