Sample Code:
<table class="grid">
<tr>
<td>click me </td>
<td class="unitNumber"><span>Unit 1</span></td>
<td class="unitStatus">Open</td>
</tr><tr>
<td class="unitNumber"><span>Unit 2</span></td>
<td class="unitStatus">Sold</td>
</tr>
</table>
I am able to get the row index of the row selected to get the exact column data.
tr = $('.grid').find('tr');
tr.bind('click', function(event) {
unitNo = $(this).find("td.unitNumber span").html();
alert(unitNo);
});
The above tr click event is fine.
My problem now is how to trigger this tr binding event when clicking the anchor link <td>Show map </td>within the table row?
Goal:
To get first the unitNo (processed on tr.bind click event) before processing the rest of the code on anchored link?
I tried to duplicate the tr click function within the anchor link click event but got undefined value on unitNo. See my code:
$('a[id^="unit_floor_plan_preview"]').bind('click',function() {
var tr = $('.grid').find('tr');
unitNo = $(this).find("td.unitNumber span").html();
alert('From link: ' + unitNo);
});
test code:
http://jsfiddle.net/VjkML/29/
Change:
unitNo = tr.find("td.unitNumber span").html();
To:
unitNo = $(this).find("td.unitNumber span").html();
In $('a[id^="unit_floor_plan_preview"]').bind('click' You try to find "td.unitNumber span" within $(this). The problem is, this refers to the link clicked on, thus you'll never find anything!
FYI, you could easily rewrite that ENTIRE statement as follows:
$(document).on("click", '.grid tr, a[id^="unit_floor_plan_preview"]', function(e) {
e.stopPropagation(); // will prevent double click events from link being clicked within row
var unitNo = $.trim($(this).closest("tr").find(".unitNumber span").text()); // trim to remove end space, closest gets closest parent of selected type
if (e.target.tagName == "A") alert('From link: ' + unitNo);
else alert(unitNo);
});
Example
The best way is to bind the event only to your tr and use the event.target to check if it is tr or any other element that was clicked. This way your click event will not be duplicated.
This should work
var unitNo;
var tr;
tr = $('.grid').find('tr');
tr.bind('click', function (event) {
if ($(event.target).is('tr')) {
// If it is a tr that is clicked then just use find
unitNo = $(this).find("td.unitNumber span").html();
} else {
// If not tr find the closest tr and then find the element
unitNo = $(this).closest('tr').find("td.unitNumber span").html();
}
alert(unitNo);
});
Check Fiddle
Try:
var unitNo;
var tr = $('.grid').find('tr');
$('a[id^="unit_floor_plan_preview"]').on('click',function(e) {
e.stopPropagation();
unitNo = $(this).closest('tr').find("td.unitNumber span").html();
alert('From link: ' + unitNo);
});
tr.on('click', function(event) {
unitNo = $(this).find("td.unitNumber span").html();
alert(unitNo);
});
jsFiddle example
With the link you need to go up the DOM to the row (via .closest()), then use .find() to go back down the same row to find the span you want to get the Unit value.
Related
Use case:
user clicks on a datatable cell. Depending on the row and column of that cell certain action should be executed.
How can I check whether that doesn't click on a certain column and if he does not click on that column, then I would retrieve information from the row he clicked on and allow him to execute an action based on that information.
I did it like this and it works:
var validColumn = false;
$('#fooTable tbody').on( 'click', 'td', function () {
validColumn = $('#fooTable').DataTable().cell(this).index().column !== 5;
});
$('#fooTable tbody').on('click', 'tr', function () {
if (validColumn) {
//do stuff
}
});
But I feel there is a more elegant approach.
First set an aria to the td to identify the position, something like
Table wiht 6 columns so
<tr aria-number="1">
<td aria-number="1">
<td aria-number="2">
<td aria-number="3">
<td aria-number="4">
<td aria-number="5">
<td aria-number="6">
</tr>
Same for tr, think is easy way to do
Use jQuery function .parent(), sending $(this), so.
var td = $(this).parent();//If the item clicked is something inside of td
var tr = $(this).parent().parent();//To select the tr where was clicked
And call the aria with
if(td.attr('aria-number') == 6){ //do something; }
Lets say I have a click event set up for all TRs, naturally each TR is filled with TDs, so when you click a TR you are also clicking a TD. Is there anyway to capture the TD (or its index) that was clicked as a result of a TR being clicked?
I thought perhaps something like this, but I'm not getting anything out of that.
$('tbody').on('click', 'tr', function(){
var thisEq = $(this+' td').index();
alert("thisEq: "+thisEq);
});
Demo
You can get the td using event.target
$('tbody').on('click', 'tr', function(e){
var thisEq = $(e.target).index();
alert("thisEq: "+thisEq);
});
Note : .index() gives 0 to n values, so you would get 0 for first td
Reverse the problem round - detect which td is clicked and detect the parent tr.
$('td').on('click', function(){
var tr = $(this).parent('tr');
alert(tr);
});
You could also do this through use of a delegated event handler. This one hooks onto each tr element but you could hook it onto the body as another submitter has just proposed
$('tr').on( 'click', 'td', function() {
...
});
<tbody>
<tr>
<td>Name1</td>
<td>Position1</td>
<td>Operation1</td>
</tr>
<tr>
<td>Name2</td>
<td>Position2</td>
<td>Operation2</td>
</tr>
</tbody>
I need to get the string in the first <td> when I click the last <td> inside the same <tr>,
for example, if I click in the <td> contains "Operation1", I could get a string with the value "Name1".
How to do this? (In reality, the strings among different <td>s have not any relationship, like the same postfix here)
Oh, BTW, this table is created by using jQuery Datatables plug-in.
Thanks a lot!
There are multiple ways to do it, such as:
$('td').parent().children().filter('td:first');
$('td').parent('tr').find('td:first');
$('td').siblings('td:first');
Here's a jsFiddle example.
Use this :
$(document).on('click', 'td:last', function(){
$(this).siblings(':first')
})
Here is a Javascript only solution for a static page, this attaches an event listener to the tr and intercepts the click events of its children. the contents of the tr can be dynamic.
Array.prototype.forEach.call(document.getElementsByTagName("table"), function (table) {
Array.prototype.forEach.call(table.getElementsByTagName("tr"), function (tr) {
tr.addEventListener("click", function (evt) {
var children = this.children,
length = children.length;
if (length && children[length - 1] === evt.target) {
alert(children[0].firstChild.nodeValue);
}
}, false);
});
});
On jsfiddle
Which in jquery terms would be
$("table tr").on("click", function (evt) {
var target = $(evt.target);
if (target.parent().children().last().get(0) === evt.target) {
alert(target.parent().children().first().text());
}
});
On jsfiddle
Or rather than set an event listener per tr element ("bubbling"), you could also use event "bubbling" and move it all the way out to document (what those at jquery call Event Delegation, jquery.on), this will allow for quite a dynamic system if you add and remove rows from your table, or even whole tables.
document.addEventListener("click", function (evt) {
var target = evt.target;
if (target.nodeName === "TD" && target.parentNode.children[target.parentNode.children.length - 1] === target) {
alert(target.parentNode.children[0].firstChild.nodeValue);
}
}, false);
On jsfiddle
Or using jquery delegation
$(document).on("click", "td", function (evt) {
var target = $(evt.target);
if (target.parent().children().last().get(0) === evt.target) {
alert(target.siblings().first().text());
}
});
On jsfiddle
I have a table full of appointments. Every appointment has two buttons. One for canceling the event, one for accepting it.
I am struggling to get the appointmentId in the jQuery function when I click on a button. Can you please give me a hint how to do this? The appointmentId is in the table as a hidden input field.
// my html code
<tr>
<td align="left">
<input type="hidden" name="appointmentId" value="234">
John Smith - 14.03.2013 at 9 o'clock
</td>
<td align="right">
<input type="button" id="acceptEvent" class="acceptEvent" value="Accept">
<input type="button" id="cancelEvent" class="cancelEvent" value="Cancel">
</td>
</tr>
// my jQuery code
$("body").delegate('.acceptEvent', 'click', function() {
console.log('accept event clicked');
// get the appointmentId here
});
$("body").delegate('.cancelEvent', 'click', function() {
console.log('cancel event clicked');
// get the appointmentId here
});
Use closest to grab the parent tr element, then select your hidden field.
The reason that this is the correct answer is because it takes the context of the click event with $(this). Then it travels up the DOM tree to your root table row element and selects the child by name. This ensures that you are always in the correct row.
EDIT: I know you already selected an answer, but this was really bothering me that it wasn't working properly. I had to walk down twice using .children() to get it to work though you could also use .find('input[name="appointmentId"]'). Even though you've already selected your answer, I hope this will help you.
$('.acceptEvent').click(function() {
var myVal = $(this).closest('tr').children().children().val();
});
$('.cancelEvent').click(function() {
var myVal = $(this).closest('tr').children().children().val();
});
In the click function, you have access to the button that was clicked with this so you can do:
$("body").on('click', '.cancelEvent', function() {
var input = $(this).closest('tr').find('input[name="appointmentId"]').val();
});
Assuming you have no other IDs or classes to key off of, you can use jQuery's Attribute Equals Selector in reference to the clicked button's parent tr element:
$('.acceptEvent').click(function() {
// get the appointmentId here
var appointmentId = $(this).closest('tr').find('input[name="appointmentId"]').val();
});
I'll do it like that :
$("body").on('.acceptEvent', 'click', function() {
var id = $('input[name="appointmentId"]').val();
//Or search in the parent <tr>
var id = $(this).parent().find('input[name="appointmentId"]').val();
console.log('accept event clicked');
console.log('Id is ' + id);
});
I have a table like below
<table onclick="dosomething()">
<tr><td>11</td><td>12</td><td>13</td></tr>
<tr><td>11</td><td>12</td><td>13</td></tr>
<tr><td>11</td><td>12</td><td>13</td></tr>
</table>
After I click on the table, I need to find the td on which the click happened. I cannot have onclick event written on tr or td.
You can do something like this (give your table a class of myClass- or whatever you want):
function tableClicked(td) {
// Do something dependent on the td which was clicked
}
$(document).ready(function () {
$("table.myClass td").click(function () {
tableClicked(this);
});
});
This means that you don't have to add onclick attributes to the <td> tags.
Add an Id to the table and remove onClick handler. this is to seperate the behavior and content.
<table id="tableId">
since event will bubble up, capture it on table element and find the target, so you don't need to add event listener to every td.
$('#tableId').click(function(e){
//the td is the target where event happens
var td=e.target;
});
$(function(){
$("#tbl").bind("click", function(e){
if(e.target.tagName == "TD"){
//do your magic
}
});
});
I would dump the onclick and do this
$("#myTable td").click(function() {
$(this).html(); // get the value
$(this).hide(); // hide it
$(this).remove(); // remove it
});
<table id="myTable">
<tr><td>11</td><td>12</td><td>13</td></tr>
<tr><td>11</td><td>12</td><td>13</td></tr>
<tr><td>11</td><td>12</td><td>13</td></tr>
</table>