How do I create click event for table row(tr) specific and table data(td).
For example, something similar like this
$("table tr").on("click", function(){
// do something with tr without td click handler
});
$("table tr td").on("click", function(){
// do something with td without tr click handler
});
Thanks in advance
To bind click event to td element so that it doesn't fire parent tr click, you need to prevent event from bubbling up DOM tree. You should call stopPropagation method of the event object:
$("table tr td").on("click", function(e) {
e.stopPropagation();
// do something with td without tr click handler
});
do something with tr without td click handler
This is also possible if you bind click event in capturing phase (read about event order). For this you will need to use HTMLElement's addEventListener method, jQuery $.fn.on method bind event in bubbling stage of the event propagation. However note, that this has little practical sense if you think about it. Most likely that you want to prevent bubbling of the event in td->tr direction on some specific table cells clicks.
Related
I have a dynamic datatable where data are loaded by Ajax.
My HTML is:
<table id="dynamic_table"></table>
and the JS is:
$(document).ready(function() {
$('#dynamic_table').DataTable( {
"ajax": '/ajax_handler',
...
$('td').on('click', function(e){
alert("I'm td")
});
$('body').on('click', function(e){
alert("I'm body")
});
Well 'body' is caught but 'td' is not. Of course the browser shows rows with their tr/td tags but it seems like that (dynamic) loaded data aren't still seen by the JS.
How I can catch clicks to my dynamic td? How I can bind them?
The problem you are running into is your DataTable create td elements after you bind those click events. There are 2 alternatives, re bind all event listenes to TD after table renders, or using event bubbling to capturate click event to parent component.
There is a jQuery on() argument you can pass to tell the table listen for click events.
$('table').on('click', 'td', function(e){
alert("I'm td")
});
Assign class to td and bind event handler to this class.
$.on('event.js-name', function(){});
i have used the event for the whole row and perform some function by ajax in the page task.php and change the style removed the class and displayed the message without refreshing the page . Eventhough i have removed the class view_task its still getting worked and doing the function how to prevent it. and also changed the class with toggle class(jquery function
$('#task tbody tr.view_task').dblclick(function(e){
var task_id = this.id.split('-');
var id = this.id;
$.post('task.php',{'task':task_id[1],'action':'update_count','type':task_id[2],'index':task_id[3]},function(data){
$('#'+id).css('background-color','white');
$('#'+id).removeClass( "view_task" );
$("#message2").html('<span id="msg">Task Viewed <img src="images/remove.png" /></span>');
});
e.preventDefault();
});
When you install an event handler like this:
$('#task tbody tr.view_task').dblclick(function(e){
it is installed initially and will remain on the object no matter what class changes you make to the object.
If you want the event handlers to be dynamic and change as the class changes, then you need to use the delegated form of .on() like this:
$('#task tbody').on("dblclick", "tr.view_task", function(e){...});
This will actually attach the event handler to #task tbody and then each time a dblclick event bubbles up to that element, it will check to see if it originated on an element that has "tr.view_task". This will allow it to only respond if the appropriate class is still on the clicked on object.
See these references for other info on delegated event handling:
JQuery Event Handlers - What's the "Best" method
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
jQuery selector doesn't update after dynamically adding new elements
Should all jquery events be bound to $(document)?
Try this:
$('#task tbody tr.view_task').unbind();
or if you only want to remove click event
$('#task tbody tr.view_task').unbind("click");
You need to unbind or off the event of .view_task class
Example:
$('#task tbody tr.view_task').off('dblclick');
OR
$('#task tbody tr.view_task').unbind('dblclick');
$('#task tbody tr.view_task').dblclick(function(e){});
Above statement finds element the bind the event with them, if you remove selector it will have no impact.
You can use either .off() to remove event handler.
$('#task tbody tr.view_task').dblclick(function(e){
var self = this;
$.post('task.php',{'task':task_id[1],'action':'update_count','type':task_id[2],'index':task_id[3]},function(data){
$(self).off('dblclick')
});
});
OR, You can use Event Delegation using .on() delegated-events approach.
$('#task tbody').on('dblclick', 'tr.view_task', function(e){
//Your code
})
Try
$("#task tbody tr.view_task").dblclick(function(e) {
if ($(this).hasClass("view_task")) {
// do stuff
$(this).removeClass("view_task")
};
e.preventDefault();
});
$("body").addClass("view_task")
.on("dblclick", function(e) {
if ($(this).hasClass("view_task")) {
// do stuff
console.log(this.className);
$(this).removeClass("view_task");
};
e.preventDefault();
});
body {
width:400px;
height:400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
dblclick
I'm using
$(document).on('click', '.mySelector', function () {
//do something
});
To delegate events to buttons.
Next I'm using .clone(true) to copy div which containing few buttons with delegated in to it events.
My question is how do I remove events form selected new created buttons?
I'm tried:
$(document).unbind('click', $(myNewDiv).find('.mySelector'));
Somehow it's removing events from all $('.mySelector') in whole document not only from this inside 'myNewDiv' object.
I have seen documentation of jQuery .off() and .undelegate() and they accept only string like selector (my div can't have any unique ID).
Is any option to remove events from selected elements inside jQuery object when they are delegated to document?
You can add a class to your clones:
var $clone = $original.clone(true).addClass("clone");
And reject that class in your delegated handler:
$(document).on("click", ".mySelector:not(.clone)", function() {
// Do something...
});
$(document).on('click', '.mySelector', function(){
//do something
});
the code above means, "attach a click handler to the document, so whenever any element that corresponds to the '.mySelector' selector is clicked, fire the handler".
whenever you clone an element, you clone its class as well, therefore it will suit the '.mySelector' too.
the handler that you have delegated is attached to the document and not to the elmenets themselves. in order for the new elements to not fire the handler, you must make them not fit the selector. so either change their class to '.mySelector2' after cloning, or whatever.
I am struggling with this code:
After choosing the html element and then applying the on click function what is the purpose of tr.
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});
The purpose of the TR is to specify what you will be clicking within the #dataTable tbody selector. Try changing it to something else and see how it behaves differently.
There's a subtle difference between:
$( "#dataTable tbody tr" ).on( "click", callback); // 1
and
$( "#dataTable tbody" ).on( "click", "tr", callback); // 2
The first selects every tr and calls addEventListener on each individually.
The second adds only one, special event listener to the tbody element. Whenever something inside is clicked, this listener checks if it is a tr and then delegates the event to your specified callback.
This gives 2 practical differences:
One listener is added, instead of potentially very many (which can improve performance in some cases),
if you add more trs dynamically in the future, they will also react to click as you'd expect.
Events bubble. That's the primary thing you need to understand. If the user clicks on an a inside a p inside a td inside a tr inside a table (and so on), the click event will bubble up each of these elements and trigger all click event listeners in turn.
$("#dataTable tbody").on("click", "tr", function() {
This chooses the #dataTable tbody element to attach the event listener to, but it will filter and only react to events triggered by a nested tr. You could also do this instead:
$("#dataTable tbody tr").on("click", function() {
But this would bind many individual event listeners to each and every tr. This may be a lot more inefficient or have other undesirable effects; for example if you keep adding or removing tr elements, you may end up with some trs which have event listeners bound to them and others without.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jQuery - Click event doesn’t work on dynamically generated elements
I just have a clickable add button that adds new table rows. The table rows include a delete button. I've noticed that when I dynamically add a new row the button does not fire the click event, but if the button exists when the page loads, then it works fine. How can I correct this?
Javascript:
$('#btnAdd').click(function () {
var newTr = '<tr><td><input id="column_0" name="column[0]" style="width:40%;" type="text" /> <img alt="Delete-icon24x24" class="btnDel clickable" id="" src="/assets/delete-icon24x24.png" /></td></tr>';
$('#columns').append(newTr);
});
$('.btnDel').click(function () {
alert('hey');
console.log('test');
var row = $(this).closest("tr");
alert(row);
row.remove();
});
You'll need to use event-delegation:
$("table").on("click", ".btnDel", function () {
/* Respond to click here */
});
The reason is that you cannot bind a handler to items that don't presently exist in the DOM. You can, however, bind a handler to a delegate target (a parent element that will remain in the DOM). Clicks will bubble up the DOM, eventually reaching the delegate target.
We listen for clicks on the table and we evaluate whether they came from an .btnDel element. This will now respond to clicks from .btnDel elements loaded when the page loaded, as well as those that are added dynamically later.
Lastly, don't re-use ID values.
You need to use on() for event delegation for dynamically added html elements. You can delegate event to parent element of dynamically added elements if you can or you can delegate to document.
$(document).on('click', '.btnDel', function () {
alert('hey');
console.log('test');
var row = $(this).closest("tr");
alert(row);
row.remove();
});
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.
For further understanding read this article Understanding Event Delegation
use on()
$(document).on('click', '.btnDel', function(){
//your code
})
This will work
$('#btnAdd').click(function () {
var newTr = '<tr><td><input id="column_0"
name="column[0]"style="width:40%;"type="text" />
<img alt="Delete-icon24x24" class="btnDel clickable" id=""
src="/assets/delete- icon24x24.png" /></td></tr>';
$('#columns').append(newTr);
$('.btnDel').click(function () {
alert('hey');
console.log('test');
var row = $(this).closest("tr");
alert(row);
row.remove();
});
});