Event onclick on <td> and <tr> - javascript

I have an onclick event in a table both on a <td> and <tr> elements. I need when the user clicks on the specific column (<td>), the <tr> event won't be triggered, only the <td> one.
How to do it ?
Example :
HTML :
<tr onclick='trclick();'>
<td>Column 1</td>
<td>Column 2</td>
<td onclick='tdclick();'>Column 3</td>
</tr>
JS :
function trclick(){console.log('tr clicked')};
function tdclick(){console.log('td clicked')};
When the user clicks on 'Column 3', both events are triggered, but i want only tdclick() to be triggered.

What you need to do is to stop the propagation of the parent event when a child is clicked, it's easy done in jQuery, but naively you need to do a little more work:
function trclick(){
console.log('tr clicked')
};
function tdclick(e){
if (!e) var e = window.event; // Get the window event
e.cancelBubble = true; // IE Stop propagation
if (e.stopPropagation) e.stopPropagation(); // Other Broswers
console.log('td clicked');
};
Note, for Firefox you need to pass a event parameter:
<td onclick='tdclick(event)'>Column 3</td>

You need to stop the propagation of the event.
to access the event object you need to use it as parameter of your function tdclick
function trclick(){console.log('tr clicked')};
function tdclick(event){
console.log('td clicked');
event.stopPropagation()
};
<table><tbody>
<tr onclick='trclick();'>
<td>Column 1</td>
<td>Column 2</td>
<td onclick='tdclick(event);'>Column 3</td>
</tr>
</tbody></table>

you can use el in your function input and pass the variable to it, in every where you wanna call it.
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
function colorChanger(el){
el.style.backgroundColor = '#007d00';
}
</script>
</head>
<body>
<table>
<tr onclick="colorChanger(this);">
<td onclick="colorChanger(this);">click me</td>
</tr>
</table>
</body>
</html>

All javascript events are invoked with an "event" object in the first argument. This object have a "stopPropagation" method, which prevent listeners of the same event on higher hierarchical DOM nodes to be triggered.
There's an example just like yours at MDN: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation
In your example, you could just stop propagation on "tdclick":
function tdclick(e){
e.stopPropagation();
console.log('td clicked')
};

I like this method:
<td style='cursor: pointer;' tdclick(event);'></td>
then JS
<script>
tdclick(){
//do something...
}
</script>

Related

Event onclick on <td> and <tr> not work

I have a table and I want to have two different onclick on tr and only on td.
to do this I have two function:
function goToLink(url) {
location.href = url ;
}
function goToLinkTd(e,url) {
if (!e) var e = window.event; // Get the window event
e.cancelBubble = true; // IE Stop propagation
if (e.stopPropagation) e.stopPropagation();
location.href = url ;
}
<tr onclick="goToLink('http://tahrircenter.com/product/bb/url')">
<td>1</td>
<td>10013</td>
<td>عنوان</td>
<td>
-
</td>
<td>10</td>
<td>
<p class="">0</p>
</td>
<td onclick="goToLinkTd(event,'http://tahrircenter.com/product/bb/url#price-change')">
<img src="http://tahrircenter.com/assets/frontend/_img/_svg/chart.svg" alt="" class="table-chart">
</td>
</tr>
but when I click on my row(tr) it goes to td's link.
http://tahrircenter.com
Use jquery events and give tr and td different classes
$(function(){
$('tr td.someClass').click(function(){
//Code here
})
$('tr.ClassName').click(function(){
//Code here
var attributeValue=$(this).attr("customName"); // you
})
})
Apply custom attribute in html
<tr customName="http://tahrircenter.com/product/bb/url">
<td></td>

jQuery - Removing td's click event after clicking it

I bind a click event to all tds like so:
$(document).ready(function(){
$("#table").on("click","td",clickHandler);
});
How to remove a particular clickHandler from a clicked td after clicking it?
If you just want each table cell to have the click event bound to it for one click, use .one():
$("td").one("click",function(){
$(this).off("click");
});
$("td").one("click", function() {
console.log($(this).text())
$(this).off("click");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Item 1</td>
<td>Item 2</td>
<td>Item 3</td>
<td>Item 4</td>
</tr>
</table>
You can try this:
$('td').toArray().forEach(td => {
td = $(td);
td.attr('onclick', 'alert(this.id)');
});
$(document).on('click', 'td', function () {
$(this).removeAttr('onclick');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table>
<tr>
<td id="td1">Item 1</td>
<td id="td2">Item 2</td>
<td id="td3">Item 3</td>
<td id="td4">Item 4</td>
</tr>
</table>
My idea: setting onclick attribute to td tag, after clicking, removing the attribute.
Try this. A different approach where you don't need to add/remove class and also no need to modify onclick attribute as inline events are not recommended.
What i'm doing here is binding the click event slightly differently.
What you are doing is $("#table").on("click", "td", clickHandler) - it will bind event to #table and upon click filter it for td.
Now what i'm doing is $("#table td").on("click",clickHandler) - it will bind the event to all td inside #table. So when the click event occurs, for that particular td click can be turned off by $(this).off("click");
$(document).ready(function(){
$("#table td").on("click",clickHandler);
});
var clickHandler = function(){
console.log(this);
$(this).off("click");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table">
<tr>
<td>Item 1</td>
<td>Item 2</td>
<td>Item 3</td>
<td>Item 4</td>
</tr>
</table>

how to access table row object from an anchor within a cell?

i have a table with a few rows. i want to access the cells with the value that are in the same row as the anchor that triggers the function populateRow();
(i hope i explained it in a clear way).
any idea how to do that?
<tr>
<td>
some value
</td>
<td>
update
</td>
</tr>
<tr>
<td>
another value
</td>
<td>
update
</td>
</tr>
The populateRow() function would need to know which anchor was clicked, so you'd need to either pass this to it to give it a reference to said anchor:
onclick="populateRow(this);"
function populateRow(anchor) {
var row = $(anchor).closest("tr");
var firstCellValue = row.find("td").first().text();
}
...and from there use .closest() to navigate up the DOM to the containing tr element.
Or, better, bind the click event handler with jQuery rather than putting it inline on every row:
$(document).ready(function() {
$("#idOfYourTable").on("click", "a", function(e) {
var row = $(this).closest("tr");
var firstCellValue = row.find("td").first().text();
console.log(firstCellValue);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="idOfYourTable">
<tr>
<td>Value 1</td>
<td>
update
</td>
</tr>
<tr>
<td>Value 2</td>
<td>
update
</td>
</tr>
</table>
(Click the "Run..." button to see it working.)
I don't know what is that populateRow() function for, but if you want to get value on the first td of the same tr, then you can try testing this:
onclick="alert($(this).closest('tr').find('td:first').text())"
if you want to pass it in populateRow() function, you can:
onclick="populateRow($(this).closest('tr').find('td:first').text())"
Or ...
It would be more neat if you pass the element then process it later inside your function:
onclick="populateRow(this)"
function populateRow(elm) {
var val = $(elm).closest('tr').find('td:first').text();
alert(val);
}
Hope this helps. Good luck!

Mouseenter not working for dynamic content

I have written a code where i need to trigger a functionality when mouse is over to specific elements.
Its working fine for below code for all static
$("table td").on("mouseenter",function(){
console.log("mouse entered")
});
but for all dynamic <td class="editcolumn">XYZ</td> event is not triggering even if i use below code
$("table td").on("mouseenter",".editcolumn",function(){
console.log("mouse entered")
});
Any idea how to make it work. I'm using jQuery 1.11
I know I just commented, but I figured I would show you an example:
HTML:
<table id="tablee" cellspacing="0">
<thead>
<tr class="tablehead">
<th>This</th>
<th>is</th>
<th>a</th>
<th>table</th>
<th>header</th>
<th>and</th>
<th>stuff</th>
<th>though</th>
</tr>
</thead>
<tr class="append">
<td class="edit-column">asdf</td>
<td class="edit-column">qwer</td>
<td class="edit-column">zxcv</td>
<td class="edit-column">rtyu</td>
<td class="edit-column">tyui</td>
<td class="edit-column">dfgh</td>
<td class="edit-column">dfgh</td>
<td class="edit-column">wert</td>
</tr>
<!-- ... -->
</table>
<br/>
<br/>
<input type="button" class="add-column" value="Add Column" />
Javascript:
$(function() {
$('.add-column').click(function() {
$('.append').append("<td class='edit-column'>iueo</td>");
$('.tablehead').append("<th>Mo columns</th>");
});
/* vvv - this */
$("#tablee").on('mouseenter', '.edit-column', function() {
/* ^^^ should be children or a child of this */
$(this).css('background-color', 'yellow');
});
});
Here is a fiddle
This question's answer gives a much better explanation of delegated events.
I too faced a similar problem for dynamic elements that are added or removed. In such situations you can create dynamic elements with event-handlers attached to their attributes i.e. in your case you can put the desired operations in a function which gets called by your attribute event handlers:
It should be something like this:
Javascript:
function whenMouseEnters() {
// perform some operations
}
Html:
<td onmouseenter="whenMouseEnters()">
If table is aviable on DOM load you can write delgated event for the td with class editColumn like this:
$("table").on("mouseenter",".editcolumn",function(){
console.log("mouse entered")
});

Click elsewhere not working in jquery

I got this code:
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('td').click(function() {
if($('#edit').length == 0) {
var idz = $(this).parent().attr('id');
var textz = $(this).text();
var rowz = $(this).attr('id');
$(this).append('<textarea id=\"edit\" style=\"position:absolute;left:0;top:0;z-index:1;\">'+textz+'</textarea>').focus();
}
});
if($('#edit').length > 0) {
$('html:not(#edit)').click(function() {
$('#edit').remove();
});
}
});
</script>
<div class="table">
<table>
<tr>
<td>ID</td>
<td>Client</td>
<td>Category</td>
<td>Active</td>
</tr>
<tr id="2">
<td>2</td>
<td>Client 2</td>
<td>1</td>
<td>1</td>
</tr>
<tr id="1">
<td>1</td>
<td>Client 1</td>
<td>2</td>
<td>1</td>
</tr>
</table></div>
What I'm trying to do here is to intercept a click on any table cell and open a small textarea with the cell's value. IT WORKS OKAY.
But the peoblem is I'm trying to close the textarea by clicking elsewhere but not the #edit. So, this part of code doesn't work:
if($('#edit').length > 0) {
$('html:not(#edit)').click(function() {
$('#edit').remove();
});
}
I tried various ways of if/else statements, one if in another and so on and it still doesn't work. Please give me a hint of what's wrong with me.
The #edit element doesn't exist on first pageload, so the event handler is never bound as the condition fails.
Also, html:not(#edit) is usually not the way to go, attach the event handler to the document and check if the click originated from within #edit, if not remove #edit.
Change this
if($('#edit').length > 0) {
$('html:not(#edit)').click(function() {
$('#edit').remove();
});
}
to
$(document).on('mousedown', function(e) {
if ( ! $(e.target).closest('#edit').length )
$('#edit').remove();
});
FIDDLE

Categories

Resources