Can I exclude a button click inside a TR click event? - javascript

I am currently highlighting a table row when selected but in one of the cells I have a button. When I click the button I am triggering the table row click event. Is it possible to seperate the two?
My two calls currently look like this:
$('table.table-striped tbody tr').on('click', function () {
$(this).find('td').toggleClass('row_highlight_css');
});
$(".email-user").click(function(e) {
e.preventDefault();
alert("Button Clicked");
});
My HTML looks like this:
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th>col-1</th>
<th>col-2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Some Data</td>
<td><button class="btn btn-mini btn-success email-user" id="email_123" type="button">Email User</button></td>
</tr>
</tbody>
</table>
Any idea how I might stop the button click event from triggering the row click event?

You have to use stopPropagation:
$(".email-user").click(function(e) {
e.preventDefault();
e.stopPropagation();
alert("Button Clicked");
});
(See also : What's the difference between event.stopPropagation and event.preventDefault?)

I believe this is caused by event bubbling, try using e.stopPropagation(); just after e.preventDefault();

Try this:
$('.table-striped').find('tr').on('click', function() {
$(this).find('td').toggleClass('row_highlight_css');
});
$(".email-user").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
});​

Related

Selecting table rows with jquery, but also selecting rows when clicking button, how do I prevent this?

When you click on a table row it adds a class that changes it's appearance to reflect it's selected.
$('#my_table tbody').on( 'click', 'tr', function () {
$(this).toggleClass('selected');
} );
However, I also have some buttons in a column that let you do things specific to the row:
Item Amount Action
--------------------------------
Apple 10 [Buy] [Delete]
Banana 5 [Buy] [Delete]
Orange 14 [Buy] [Delete]
When I click one of the individual buttons, it also triggers the table row '.selected' class to be added, but I don't want this to occur when clicking buttons.
You can use Event​.stop​Propagation() on button click:
$('#my_table tbody').on( 'click', 'tr', function () {
$(this).toggleClass('selected');
} );
$('#my_table tbody').on( 'click', 'button', function (e) {
e.stopPropagation();
});
.selected{
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="my_table">
<thead>
<th>Item</th>
<th>Amount</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>10</td>
<td><button>[Buy]</button><button>[Delete]</button></td>
</tr>
<tr>
<td>Banana</td>
<td>5</td>
<td><button>[Buy]</button><button>[Delete]</button></td>
</tr>
<tr>
<td>Orange</td>
<td>14</td>
<td><button>[Buy]</button><button>[Delete]</button></td>
</tr>
</tbody>
</table>
You can use stopPropagation() or preventDefault() on buttons onclick event. This will prevent event bubling to parent elements of button (td, tr, table and so on). Assuming your buttons class as 'row-button' following is a sample code:
$('.row-button').on('click', function(event)){
event.stopPropagation();
//Do what are intended upon button click.
}
You might make sure that the td being clicked on is not in the column with the buttons. With :not, you can ensure that the matched element doesn't match a particular selector, and with :nth-child, you can specify the 3rd td in its container as the one to be excluded:
$('#my_table tbody').on('click', 'tr td:not(:nth-child(3))', function() {
console.log('click registered');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="my_table">
<tr>
<td>td 1</td>
<td>td 2</td>
<td><button>button</button></td>
</tr>
</table>
You are experiencing a feature of the DOM called Event Propagation.
What you want to do is prevent this from occurring by calling Event.stopPropagation() in the handlers for your <td> clicks
To stop propagation with a jQuery event handler, simply return false on the last line of your td click handlers.

delegate checkbox within my table row

<tbody>
<tr>
<td><input type="checkbox"/></td>
<td>453</td>
<td>Nick James</td>
<td>12/9/2016</td>
</tr>
</tbody>
JS
$('body').on('click','#myTable tbody',function(e){
alert('do something');
});
I have checkbox within my table row, how do I delegate it form above's click event? I do not want the event to be occur when I click on the checkbox.
To perform the functionality only when target type is not checkbox
$(document).ready(function(){
$('body').on('click','#myTable tbody',function(e){
if(e.target.type!='checkbox')
alert('do something');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id='myTable'>
<tbody>
<tr>
<td><input type="checkbox"/></td>
<td>453</td>
<td>Nick James</td>
<td>12/9/2016</td>
</tr>
</tbody>
</table>
You can check if the target is checkbox and prevent further execution:
$(document).ready(function(){
$('body').on('click','#myTable tbody',function(e){
if($(e.target).is(':checkbox'))
{
return;
}
alert('do something');
});
})
Check this Fiddle
Use stop event.stopPropagation() to prevent the click on inner element to bubble across the parents.
$('body').on('click','#myTable tbody input[type="checkbox"]',function(event){
event.stopPropagation();
});
$('body').on('click','#myTable tbody',function(e){
alert('do something');
});
Now the alert will come only when you click on anywhere inside the table, which is not a input[type="checkbox"].
try this
You can use Jquery not and has selectors to achieve this
$('body').on('click','#myTable tbody td:not("td:has(input[type=checkbox])")',function(event){
alert('do something');
});
Working FIDDLE

How to hide all tr from table except clicked one

I want to hide all <tr> of the table except on which I clicked.
<table>
<tr>
<td>ABC</td>
<td>DEF</td>
<td><i class="delete">delete </i></td>
</tr>
<tr>
<td>ABC</td>
<td>DEF</td>
<td><i class="delete">delete </i></td>
</tr>
</table>
On click of delete button hide all rows except current.
Jquery code:-
$(document).ready(function () {
$('table tbody tr').siblings().not($(this)).hide();
});
Please suggest me.
Use siblings as follow:
See the comments inline in code:
// Bind click event on `tr` inside `table`
$('table').on('click', 'tr', function () {
// Show current `tr` and hide others
$(this).siblings().hide();
});
Demo: http://jsfiddle.net/tusharj/LL0c2efg/
You need to run your code under a click event handler, not when the page loads. Also note that .not(this) is redundant when using siblings() as the originating element would not be included anyway. Try this:
$(document).ready(function() {
$('table tbody tr').click(function() {
$(this).siblings().hide();
});
});
Example fiddle
$(document).ready(function () {
$('table tbody tr').click(function(){
$('table tbody tr').hide();
$(this).show();
})
});
DEMO

How to detect change inside jquery Event?

I have a html table with rows.
Each row has a action column with a button and when pressing this button i want to show a input field in the second td which the user have to fill out and submit, first then the event/click is completed else the input should disappear again.
<table>
<thead>
<tr>
<th>ID</th>
<th>user-Input</th>
<th>data3</th>
<th>data4</th>
<th>data5</th>
<th>Action</th>
</tr>
</thead>
<tbody id="customers">
<tr>
<td>1</td><td></td><td>data</td><td>data</td><td>data</td><td><button type='button' class='acceptCustomerBut'>GO</button></td>
</tr>
</tbody>
</table>
javascript/jquery
$(document).on("click", ".acceptCustomerBut", function(e) {
e.preventDefault();
$(this).parent().parent().find("td:nth-child(2)").html("<input type='number' name='customer_id'>");
// DO SOMETHING
});
DO SOMETHING - im thinking if its possible to make the function detect if the input has received values with jquery's .on("change") if not, hide the input field?
Try this,
$(document).on("click", ".acceptCustomerBut", function(e) {
e.preventDefault();
var $td=$(this).closest('tr').find("td:eq(1)");
if($td.find('input').length){ // check input length, if exists then hide it
$td.find('input').hide();
} else { // else add it
$td.html("<input type='number' name='customer_id'>");
}
});
Live Demo

jQuery Children selector question

I have the following code:
$("#Table1 tbody").children().each(function(e){
$(this).bind('click',
function(){
// Do something here
},
false)
});
The Table1 html table has 2 columns; one for Names and one for a <button> element.
When I click on a table row, it works fine. When I click on the button, the button code fires; however, so does the row code.
How can I filter the selector so the button doesn't trigger the parent element's click event?
This is what you want.
It's stopPropogation that will stop the parents.
<table>
<tr>
<td>The TD: <input type="button" id="anotherThing" value="dothis"></td>
</tr>
</table>
<div id="results">
Results:
</div>
<script>
$(function() {
$('#anotherThing').click(function(event) {
$('#results').append('button clicked<br>');
event.stopPropagation();
});
$('td').click(function() {
$('#results').append('td clicked<br>');
});
});
</script>
Here's a link to an example of it working as well:
http://jsbin.com/uyuwi
You can tinker with it at: http://jsbin.com/uyuwi/edit
You could also do something like this:
$('#Table1 tr').bind('click', function(ev) {
return rowClick($(this), ev);
}); //Bind the tr click
$('#Table1 input').bind('click', function(ev) {
return buttonClick($(this), ev);
}) //Bind the button clicks
function rowClick(item, ev) {
alert(item.attr('id'));
return true;
}
function buttonClick(item, ev) {
alert(item.attr('id'));
ev.stopPropagation();
return true;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="Table1">
<tbody>
<tr id="tr1">
<td>
The TD: <input type="button" id="button1" value="dothis" />
</td>
</tr>
<tr id="tr2">
<td>
The TD: <input type="button" id="Button2" value="dothis" />
</td>
</tr>
</tbody>
</table>
Is it possible to remove the button code and just run the row code, therefore kind of using event bubbling.
Another couple options:
can you add a class to the TD that has the button in it and in the selector, do '[class!="className"]'
maybe try event.preventDefault(). You can see it being used here. this way you can prevent the default action that is triggered when the button is clicked, although I'm not sure if it will completely prevent the bubbling.

Categories