Onclick event not triggered on span elements appended after AJAX call - javascript

I am retrieving some data using Ajax and appending it as span element. Below is the simplified version of the code.
function fetchPost() {
$.getJSON(urlContent, function(data) {
$.each(data.query.pages, function(i, item) {
$("#feed").append("<span id='random'> randomtitle </span>");
}
});
});
return 1;
}
$(document).ready(function(){
$('span').click(function() {
var text = $(this).text();
alert(text);
});
});
The onclick event is not triggering for span elements which was appended with the help of the AJAX call. The span elements which were present in the html before is responding to onclick event. What should I do?

The problem is you are trying to listen to elements that don't yet exist.
The solution is to use event delegation, and listen to the parent element:
$("#feed").on('click', 'span', function() { /* ... */
http://api.jquery.com/on/

Related

adding element using loop in jquery doesn't appear in dom

I am adding elements using a json call. The issue I have is that if I append an item outside the loop it appears in the DOM and I can select it, if I appended in the loop I cannot select it?
Any help would be appreciated.
<ul data-role='listview' class='ui-listview' id="DivLogOut" >
</ul>
<script type="text/javascript">
$(document).ready(function () {
$("#DivLogOut").append($("<li class='PersonLogout'>TEST ITEM</li>"));
$.get("api/StaffLoggedIn.ashx?loid=" + loid, function (data) {
var jsonobj = $.parseJSON(data);
$(jsonobj).each(function (i, item) {
$("#DivLogOut").append($("<li class='PersonLogout'>TEST ITEM</li>"));
})
})
$(".PersonLogout").click(function () {
alert("test");
})
})
</script>
Dynamically appended element use with on()
$(document).on("click",".PersonLogout",function () {
alert("test");
})
when added dynamically, you need to re-add the listener to your DOM element, this way Jquery knows which one to call. i suggest you add your .click method in a function that you can call after the async loop is done (your $.get) EX:
<ul data-role='listview' class='ui-listview' id="DivLogOut">
</ul>
<script type="text/javascript">
$(document).ready(function() {
$("#DivLogOut").append($("<li class='PersonLogout'>TEST ITEM</li>"));
$.get("api/StaffLoggedIn.ashx?loid=" + loid, function(data) {
var jsonobj = $.parseJSON(data);
$(jsonobj).each(function(i, item) {
$("#DivLogOut").append($("<li class='PersonLogout'>TEST ITEM</li>"));
})
addListener();
})
function addListener() {
$(".PersonLogout").click(function() {
alert("test");
})
}
addListener();
})
</script>
Please use .on instead of .click method. .on method will work for dynamically added elements.
$(document).on("click",".PersonLogout",function () {
//You can access the item using $(this)
});
You're creating an element after the document has loaded. AFAIK elements that are dynamically created after the document has loaded has no event binded on it.
What you can do is to bind the event on document. Remove the click event in the document ready function.
$(document).on('click', '.PersonLogout', function()
{
alert('I have been clicked!');
});
You need to listen the event outside the reloaded view, apparently $("#DivLogOut").
$("#DivLogOut").on('click', '.PersonLogout', function(){
....
});
For sure, it works ;)

Jquery on php in div box not working

I have an main php that load a php into a div box via a dropdown list.
The loaded php contains a table. There is jquery in it that does an alert on row clicked.
$(document).ready(function() {
$('#newsTable tr').click(function(){
var clickedId = $(this).children('td:first').text();
alert(clickedId);
});
});
But after it is loaded into the div, the script is not firing
use Event delegation to attach event. Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
$(document).ready(function() {
$(document).on('click','#newsTable tr',function(){
var clickedId = $(this).children('td:first').text();
alert(clickedId);
});
}); // End
There is something with event delegation. Try using this code :
$('id_Or_Class_container_hold_the_php_data').on('click', 'tr', function(){
var clickedId = $(this).children('td:first').text();
alert(clickedId);
});
replace
(document).ready(function() {
with
$(document).ready(function() {
try this
jQuery(document).ready(function($) {
$('#newsTable tr').click(function(){
var clickedId = $(this).children('td:first').text();
alert(clickedId);
});
});
I think you need to use live query, instead of your click event u can use following.
$('#newsTable tr').on('click',function()
Use below code..i think its working properly.
$(document).ready(function() {
$("#newsTable").on('click','tr',function(){
var clickedId = $(this).children('td:first').text();
alert(clickedId);
});
});

jQuery not working on a jQuery generated HTML tag

I generated multiple li in a string to have a dynamic display of a user list (connected or not).
At the end of the list, I added a li that's the button to disconnect.
Problem is, if I add it in my original code by default, without generating it, the Ajax function works fine.
If I generate it, it doesn't even apply the preventDefault().
Why is that, and how to fix this issue ?
function displayUsers() {
$.ajax({
url: 'getUsers.php',
dataType: 'json'
}).done(function (aUsers) {
if (aUsers != null) {
var sUserList = '';
$.each(aUsers, function (key, oUser) {
sUserList += '<li><span class="glyphicon glyphicon-ok" style="color: springgreen;"></span>' + oUser.nickname + '</li>';
});
sUserList += '<li class="divider"></li>';
sUserList += '<li class="disconnect"><span class="glyphicon glyphicon-off"></span>Sign Out</li>';
$('ul.dropdown-menu').html(sUserList);
} else {
var sNoConnectionMessage = '<li><span class="glyphicon glyphicon-remove-sign" style="color: crimson;"></span>Aucune connexion en cours.</li>';
sNoConnectionMessage += '<li class="divider"></li>';
sNoConnectionMessage += '<li class="disconnect"><span class="glyphicon glyphicon-off"></span>Sign Out</li>';
$('ul.dropdown-menu').html(sNoConnectionMessage);
}
});
}
setInterval(displayUsers, 1000);
$('li.disconnect a').on('click', function (event) {
event.preventDefault();
$.ajax({
url: 'logoff.php'
}).done(function () {
$('div.LoginChat').removeClass('hide');
$('div.WriteMessage').addClass('hide');
})
});
Please guide me the correct way to achieve my objective.
Event handlers are attached to elements, not to selectors.
When you do this:
$('li.disconnect a').on('click', function (event) {
jQuery will identify matching elements for 'li.disconnect a' once, and only once, at the time this line of code executes. Any matching elements added to the DOM afterward will not have been identified. In order to do that, you need to attach the click handler to a common parent element (which doesn't change during the life of the DOM) and use the overload of .on() which filters events from child elements. Something like this:
$(document).on('click', 'li.disconnect a', function (event) {
This will attach the handler to the document element (though any common parent element will work) instead of the identified elements. As events "bubble up" through the DOM they will eventually reach that parent element. The second selector in the .on() function then filters those child elements to respond only to click events which originated from an identified element.
I've written more on the subject here.
Use Event Delegation and delegate the click handler to something that doesn't get regenerated, such as the document:
$(document).on('click', 'li.disconnect a' function (event) {
...
});
The issue is if you don't delegate to something higher, the event handler is lost when you destroy the element.

Trigger click event on DOM element

I tried to trigger a click event on an selected DOM element but my code won't work.
You can see my attempt on JSFiddle.
<ul class="list-group">
LG GOLA 8M
LG 5-6M
LP 5-6M
</ul>
$(document).ready(function() {
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
});
When the DOM was loaded I collect some data from URL parameters and compare the data with DOM elements. This part works fine.
After that I get an element and I would like to trigger an click event. The click event should "execute" a specified function.
Have anyone a good solution for me? Thanks in advance.
http://jsfiddle.net/azg2R/2/
Put the click event on top in the ready event.. The click event needs to be triggered after registering the event. It was not happening before
$(document).ready(function() {
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
});
The problem is that you are triggering click event before attaching event handler to it. So you just need to move click handler before triggering click and everything would work as you expected:
$(document).ready(function() {
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
});
JSFiddle

Table onclick rows jQuery

I've a table whose content is getting generated via an AJAX success response.
HTML code
<table class="table table-hover" id="table_content"></table>
AJAX code
$.ajax({
dataType: "json",
type : "POST",
url: "/configuration/",
data : { 'selected_item' : selected_item_id },
success : function(result){
var table_heading = "<tr>"
var table_content = ""
for (var heads in result[1]){
table_heading +="<th style='background-color:#f1f1f1;'>" + result[1][heads] + "</th>"
}
for (var region in result[0]){
table_content += "<tr>"
for (var details in result[0][region]){
table_content += "<td>" + result[0][region][details] + "</td>"
}
}
table_content = table_heading + table_content
$("#table_content").html(table_content)
},
});
I want to apply an onclick function to it. Like this:-
Onclick function code
$(function(){
$('#table_content tr').click(function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
The issue that I'm facing is that I'm not able to click the row, if I generate the content via AJAX response. If I create a table inside the HTML itself, it'll work, but not when the table is created via AJAX response.
What's the problem? Please sugggest.
EDITED
What I'm trying to achieve is that a div should be slide down just below the row upon clicking the row. I does works for the first time when the data gets generated via AJAX. but it does not works when I'm generating data after the first time, though the event is triggered but $('.test').slideUp(0) $(this).append(($('.test')).slideDown('slow')); does not works after the first time. Nor any error is popped . See http://jsfiddle.net/fVz6D/5/
Updated:
See working demo: http://jsfiddle.net/c5FgG/1/
Your problem was that you attached the test div element to a table row, which dissapeared after repopulating the table. Instead, clone the test div on each click when you are changing the table content, and use the clone instead the original.
Old answer:
Add the onclick function code inside the ajax success function. It works out for me this way:
...
$("#table_content").html(table_content);
$('#table_content tr').click(function () {
alert("Clicked");
//your code
});
...
And don't forget to close the table rows with:
table_content += "</tr>";
The way you are using click to bind the event only binds the event to elements that are present in DOM at time the binding code is executed. You need event delegation for binding event with dynamically generated html elements using on().
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
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. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers, reference.
Try
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
The on() handler should work on newly created elements too.
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
Here Is a list of fiddles :
fiddle1
fiddle2
fiddle3
fiddle4
You can use it as per your requirement.
Use on() for dynamically added elements like,
$('#table_content').on('click',' tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
Updated your div will move to tr which you clicked, so when you click on list it will generate new content in table so your div.test will be removed from HTML, thats why you are not getting the desc div again.
To solve this problem you have to add div.desc again in clicking of list like,
if(!$('body > div.test').length){
$("body").append('<div class="test">You slide down a row with content xyz</div>');
}
Full code
$('#list').on('click', 'li', function () {
var id = this.id;
var table_content = "";
// IF id=1,2,3,4,5 Code
$("#table_content").html(table_content);
// add below code foe div.desc
if (!$('body > div.test').length) {
$("body").append('<div class="test">You slide down a row with content xyz</div>');
}
});
Demo
Alternatively, you can use clone() like,
$(function () {
$('#table_content').on('click', 'tr', function () {
$clone=$('.test:not(.new-test)').clone();// clone the first test class element
$('.new-test').remove();// remove the cloned elements
$clone.addClass('new-test').appendTo('body');// add the clone to body
$clone.slideUp(0);// playing with clone now
$(this).append($clone.slideDown('slow'));
});
});
Working demo

Categories

Resources