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();
});
});
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 the following jquery code
$(".delete").on('click', function (e){
e.preventDefault();
var id = $(this).prop('id');
console.log('Delete button id: '+id);
var formWrapper = $(".form-wrapper:nth-child("+id+")");
console.log(formWrapper);
formWrapper.remove();
});
the delete .delete is on a button inside a form
<button class="btn btn-danger delete">-<button>
and the button is loaded on the paged ynamically after the page has loaded. So I used the on function to attach the click event on it. But it won't work and the function is never called. Isn't on supposed to work not only for elements that are on the page during load but for those that get loaded afterwards?
You are saying that the particular button is getting loaded to the DOM dynamically, so in this context you have to use event-delegation to make your code working.
Normally your code will register event for the element with the class .delete immediately after the DOM loaded. Actually we dont have any elements with that identity at that time, So this context is opt for event-delegation.
I actually dont know the exact dom structure of yours, so that i have used document to delegate the click event, But you should prefer some static parent of that element to implement it,
Try,
$(document).on("click",".delete", function (e){
You need to use event delegation for dynamically generated elements. thus use .on() using delegated-events approach.
i.e.
$(document).on('event','selector',callback_function)
Use
$(document).on('click',".delete", function (e){
In place of document you should use closest static container.
The 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, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.
you should either use,
$(document).on('click',".delete", function (){});
or
$(".delete").click(function(){});
You can try jquery delegate() Method.
In jquery version 7 there was a term live however in latest one its removed and replace with delegate
you can check below example
HTML
< div class="delete"> Click Here < /div >
Javascript
$(document).delegate( ".delete", "click", function() {
alert("Hi")
});
This might help: http://jsfiddle.net/webcarvers/7Qtd7/
HTML:
<button id="one" class="delete"type="button">Id on me</button>
<div id="one">This is the div to remove</div>
JS:
$(document).ready(function(){
$("button.delete").on('click', function(){
var id = $(this).attr("id");
$("div#"+id).remove();
});
});
I have a few generated div's on my page listing events on a calender, they all have the same class "fc-event-inner". I would like to add a onclick to these div's but am struggling to get this right.
This is what iv tried, no onclick is added and no errors on page.
$(document).ready(function () {
$('.fc-event-inner').each(
function (element) {
Event.observe("click", element, EventClick);
}
);
function EventClick() {
alert("You clicked an event")
}
});
This is an example of a generated event div:
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br>by Santa</span>
</div>
Use the delegate version of on
$(document).on("click", ".fc-event-inner", function(){
/// do your stuff here
});
This catches the click at the document level then applies the class filter to see if the item clicked is relevant.
Example JSFiddle: http://jsfiddle.net/BkRJ2/
In answer to comment:
You can access the clicked element via this inside the event function. e.g.
$(document).on("click", ".fc-event-inner", function(){
var id = this.id; // Get the DOM element id (if it has one)
var $this = $(this); // Convert DOM element into a jQuery object to do cool stuff
$this.css({'background-color': 'red'}); // e.g. Turn clicked element red
});
*Note: You should never have to run an Each in order to catch events on multiple items that have a common class.
You do not need each() to bind event to elements with specific class, just selector is enough. Use jQuery on() with event delegation it will bind event to those which are generted after the binding code.
$(document).on("click", ".fc-event-inner", function(){
alert("click");
});
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, jQuery doc.
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br />by Santa</span>
</div>
Your JS:
<script>
$(document).ready(function () {
$('.fc-event-inner').on("click", EventClick);
function EventClick() {
alert("You clicked an event")
}
});
</script>
http://jsfiddle.net/UBhk9/
Some explanation:
Because you are using a class(it may be used multiple times, in contrast to an id) it will work for all the elements with this class name. The .on method will attach the event handler(in this example "click") to the selector(the class .fc-event-inner). If you want to remove events bounds you've to use the .off() method and if you only want to attach the event once you can use the .one() method.
I have create dynamic html buttons and I want to set click event to them. Here is my html output and codes :
<td style="width:90px;">
<input type="button" class="btn_Yeni" id="btnYeni"></td>
$(".btn_Yeni").on("click", function () {
alert('asd');
});
$(".btn_Yeni").trigger("click");
Nothing happens after I click the button. Do you have any suggestion?
Since the html buttons are added dynamically, you need to use event delegation to register the event handler like:
// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document).on('click', '.btn_Yeni', function(event) {
alert('asd');
});
UPDATE
Since, the buttons are added to a table cells, as visible in your HTML markup, you can do this:
$('#tableID').on('click', '.btn_Yeni', function(event) {
alert('asd');
});
This will attach your event to any button within the #tableID element,
reducing the scope of having to check the whole document element tree and increasing efficiency.
Since you have dynamic buttons you need to use event delegation.
Just using .on() to register event handlers does not make use of event delegation, it has a very specific format for making use of event delegation. The event should be attached to an element which is already present in the page(like the document object in the below case) then the dynamic element selector has to be passed as the second parameter to the on() method
$(document).on("click", ".btn_Yeni", function () {
alert('asd');
});
This is the approach when using dynamic elements.
$("body").on("click",".btn_Yeni", function () {
alert('asd');
});
How is it done:
the handler is not attached to the element itself ( cuz it does not exists when registering) -
so you attach the handler to the body element. and via event bubbling - the delegate element is checked(against) when it reaches the body ( where the handler is actually attached to).
I have put together a fiddle for you to explore dynamic button additions and using the on method for event delegation.
<ul id="btnCollection">
<li>
<input type="button" class="btn_Yeni" value="Your Button" />
</li>
</ul>
var button = $("#btnCollection:last-child").html();
$("#btnCollection").on("click", ".btn_Yeni", function (event) {
alert("Adding another button");
$("#btnCollection").append(button);
});
http://jsfiddle.net/itanex/yak7c/
DEMOenter link description here
$(document).on("click", ".btn_Yeni", function () {
alert('asd');
});
function addrow(){
var $tr = $("#baserow")
var $clone=$tr.clone();
$tr.after($clone);
}
Maybe i should be more specific.
I've a javascript function, called from here:
<input id="Text1" type="text" onkeyup="Trova('Text1');" />
The function, search into an array and, with jquery, draws new rows into a table (ID #tabdest):
$("#tabdest").append('<tr><td class="preview" nome="' + nomi[i] + '" >' + nomi[i] + '</td></tr>');
Everythings is ok until now. Into my .js file I've this function that shoud be executed:
$(document).ready(function () {
$(".preview").mousemove(function (event) {
...
This function works correctly if I write a table manually but doesn't if jQuery write it.
I'm sorry for my terrible English, hope to find help
Thanks anyway
Use .on()
As elements are added dynamically you can not bind events directly to them .So you have to use Event Delegation.
$("#tabdest").on('mousemove','.preview',function(event){ ... });
Syntax
$( elements ).on( events, selector, data, handler );
Although the other answers have correctly identified that you should be using event delegation (through the use of jQuery's on function) I wanted to explain a bit about how your code is currently working.
$(document).ready(function () {
$(".preview").mousemove(function (event) {
...
Translated into words this is: When the document is ready search for all elements with class "preview" and add an event handler to these elements for the mouse move event. jQuery doesn't do magic.
$('.preview')...
is basically doing
document.getElementsByClassName('preview')
It's not doing any kind of mapping or binding to the DOM. This means when you add a new element with the class "preview" the code that added the event handlers would need to run again to pick this new element up.
Using:
$("#tabdest").on('mousemove', '.preview', function(e) { });
Binds the event handler to the "tabdest" element (which doesn't change) and when a user clicks on a child of this element (one of your newly created elements) the event bubbles up the DOM and runs this function.
Since the preview tabel cell is added dynamically, you need to use event delegation to register the event handler:
// New way (jQuery 1.7+) - .on(events, selector, handler)
$('#tabdest').on('mousemove', '.preview', function(event) {
alert('testlink');
//....
});
This will attach your event to any table cell with class preview within the #tabdest table element, reducing the scope of having to check the whole document element tree and increasing efficiency.