Table onclick rows jQuery - javascript

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

Related

jQuery onChange event handler firing function twice

This is the table http://jsfiddle.net/djochw6L/1/
The event is supposed to fire when I enter value in the item column
$(document).on('change', '.item', function() {
var ite = $(this).closest('tr');
getdetails(ite);
})//event
function getdetails(dat){
var itemName = $(dat).find('.item').val();
alert (itemName);
};
The event handler works correct for the first row. But from the second row onwards it fires twice. Why is this?
The reason why it's firing twice is because your on change element fires for every class with the name item. If you look through your code you can see that on top of giving every table column the class item, you are also passing the item class to each row that is added. So the event fires twice, once for the row and once for the item column.
The code that's giving you the problem is
prot.attr("class", id + " item")
Try to fix your problem by not passing the item class to the table rows, instead of doing all kinds of hacky stuff to the event listener.
You could build your code to something along the lines of
prot.attr("class", "item-" + id)
try adding return false:
$(document).on('change', '.item', function () {
var ite = $(this).closest('tr');
getdetails(ite);
return false;
}) //event

on.click not working after first click on dynamically created table

I dynamically create a table full of links of 'actors', which allows to pull the actors information into a form to delete or update the row. The delete button only pops up when you select an actor.
I'm able to click a row, pull the information into the forms, and delete it on first try. However when I attempt to add a new 'Actor' and then delete it, or just delete an existing 2nd row, the button 'Delete Actor' doesn't work. It's only after the first successful delete does the button no longer work.
var addActor = function() {
// Creates a table of links for each added actor with an id based from # of actors
$("#actorsTable").append("<tr><td><a href='' onclick='deleteActor(this)' class='update' data-idx='" + actors.length + "'>" + newActor.fName + " " + newActor.lName + "</a></td></tr> ");
$(".update").off("click");
$(".update").on("click", selectActor);
};
var deleteActor = function(e) {
$("#deleteActor").on('click', function(event) {
event.preventDefault();
var row = e.parentNode.parentNode;
row.parentNode.removeChild(row);
clearForm(actorForm);
actorState("new");
});
};
I'm new to jQuery/javascript, and I'm pretty sure its due to the change in DOM, but I just don't know what to change to make it work.
Here is an Example of it in action
Try
var deleteActor = function(e) {
$("#deleteActor").unbind();
$("#deleteActor").on('click', function(event) {
event.preventDefault();
var row = e.parentNode.parentNode;
row.parentNode.removeChild(row);
clearForm(actorForm);
actorState("new");
});
};
Here is the link for unbind.
http://api.jquery.com/unbind/
The problem is because you're adding another click handler (in jQuery) within the click handler function run from the onclick attribute. You should use one method or the other, not both. To solve the problem in the simplest way, just remove the jQuery code from the deleteActor() function:
var deleteActor = function(e) {
var row = e.parentNode.parentNode;
row.parentNode.removeChild(row);
clearForm(actorForm);
actorState("new");
};
when you add html dynamically you need to attach the event to the parent static element like so:
$("#actorsTable").on("click","a.update", function() {
$(this).closest("tr").remove();
});

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.

Onclick not working on Knockout array binded fields

Im working on a CRUD Table populated using Knockout. jQuery Click event is not working on new pushed elements to the observable array
click event function
$('td').on('click', function () {
var spanElement = $(this).find('span');
$(this).find('span').hide();
$(this).find('input').show().select().on('blur', function () {
$(this).hide();
spanElement.show();
});
});
This code is working for all rows populated on-load, but not for those I add using add button.
Why is it so? How to fix it?
JSFiddle
It does not work because you are adding the event handler directly to the table cells. When you add new rows, you never add the click element.
To solve this problem, apply the click event to the table and let event delegation take over
$('table').on('click', 'td', function () {
var spanElement = $(this).find('span').hide();
$(this).find('input').show().select().on('blur', function () {
$(this).hide();
spanElement.show();
});
});
Try this
$(document).on('click', 'table td', function () {
//Your Functions
});

jQuery: How to undelegate a broad delegate on one table column?

Here's the scenario:
I am creating a dblclick delegate on a bunch of table cells that contain a class called 'canEdit'. In a specific instance, I want to remove this delegate, and add a column-based delegate that overwrites the existing one.
Here's what I have:
$('#' + tableID).delegate('tbody tr td.canEdit', 'dblclick', function () {
// Code Here
});
When a specific property is set, this is what is run:
$('#' + tableID).undelegate('tbody tr td.canEdit', 'dblclick');
$('#' + tableID).delegate('tbody tr td:nth-child(' + index + ').canEdit.select', 'dblclick', function () {
// Code Here
});
I am assuming one of the issues is that I'm removing the delegate on everything. Is there a way I can just overwrite and/or remove the first delegate only on the column? Any ideas of a workaround without having to create an entirely new class?
You could use a conditional to run different code within the handler
$('#' + tableID).delegate('tbody tr td.canEdit', 'dblclick', function () {
if( $(this).index()==7) ){
/* code for 8th column*/
}else{
/* code for other columns*/
}
});

Categories

Resources