jquery bind data to click event for object created dynamically - javascript

Script below create button and event dynamically. I want to bind data to click event. But bind() function failed, click event just won't trigger. Anyway, click event successfully triggered if I'm using on() function.
http://jsfiddle.net/hzLv1r6s/2/
function showMessage(evt) {
alert(evt.data.message);
}
$(document).ready(function () {
var activeDiv;
var pVar = { message:'Hello from a paragraph'};
$("a").on("click", function () {
if (activeDiv === $(this).attr('id')) {
$('#__div').hide('slow');
activeDiv = '';
return;
}
$('.box1').empty();
var guts =
'<div id="__div" style="display:none;">' +
'<input type="text" id="__text" value="' + $(this).attr('data-content') + '"/><br>' +
'<button id="__internal" value="aaa">Submit</button>' +
'</div>';
//this one doesn't work on click event
$('#__internal').bind('click',pVar,showMessage);
$($.trim(guts)).appendTo('.box1');
$('#__div').show('slow');
activeDiv = ($(this).attr('id'));
});
/*
//this one does work on click event
$('.box1').on('click','#__internal',function(event){
//alert(event.target.value);
alert($('#__text').val());
});
*/
});

You need to use event delegation at this context,
$('.box1').on('click','#__internal' , showMessage);
Or try to bind the event to it after that html string got appended into the DOM.
$($.trim(guts)).appendTo('.box1');
$('#__internal').bind('click',pVar,showMessage);
NOTE: But i don't know why are you refusing to use event delegation here.
DEMO created without event delegation.

Related

Not able to alert/access the changed id after cloning

My code is :
var draggedElement = this.template.querySelector("[id='"+divId+"']");
var cln = draggedElement.cloneNode(true,true);
cln.classList.add('completed');
cln.classList.add('box-height');
cln.id='clone-'+divId;
event.target.appendChild(cln);
Now if I want to alert the event target id on the onclick event it gives empty result.
Trying to use like this but did not work.
const btn = this.template.querySelector("[id='clone-"+divId+"']");
btn.addEventListener('click', function(event){
console.log('Button Clicked');
console.log(event.target.id);
});
Can anyone please help? Thanks in advance.
You are probably binding the event handler before the dragged element is created (which I suppose is done in response of a user action).
Instead of playing with id attributes, just bind the event handler at the moment you add the cloned element to the document. At that time you have the reference to the cloned element, so you can just add the event listener to it.
Little, simplified, demo:
var draggedElement = document.querySelector("#test");
var cln = draggedElement.cloneNode(true,true);
cln.removeAttribute("id"); // Don't use `id`
cln.textContent = "cloned " + cln.textContent;
document.body.appendChild(cln);
cln.addEventListener('click', function(event){
console.log('Cloned button Clicked');
});
<button id="test">test</button>
Event Delegation
Although I would strongly advise against using dynamically generated id attributes, if you really require to identify elements by such id attributes, then use event delegation:
setTimeout(function () { // In reality this would be some drag event handler
var draggedElement = document.querySelector("#test");
var cln = draggedElement.cloneNode(true,true);
cln.id = "cloned-" + cln.id; // Bad practice
cln.textContent = "cloned " + cln.textContent;
document.body.appendChild(cln);
}, 500);
// Event delegation
document.body.addEventListener('click', function(event){
if (event.target.id = "cloned-test") {
console.log('Cloned button Clicked');
}
});
<button id="test">test</button>

"$(...).find(...)" in onclick-eventhandler

I am using this code for the click handling on a button inside my page:
$(document).on("click", $('#' + GlobalVariables.currentUserType).find(".addDocumentToSection"), function (e) {
addItemToDocumentGrid();
$('#removeDocumentFromSection').disable(true).addClass("disabled");
$('#removeSelection').disable(true).addClass("disabled");
});
But the event fires as soon as I click anywhere in the page. Even if it is not the supposed button which I want to select with $('#' + GlobalVariables.currentUserType).find(".addDocumentToSection").
$('#' + GlobalVariables.currentUserType).find(".addDocumentToSection") returns one element which is actually the button which I want to be selected.
Why does it behave like that?
If you want to use event delegation, the second argument should be a selector, not a jQuery object.
$(document).on("click", '#' + GlobalVariables.currentUserType + " .addDocumentToSection", function (e) {
// ---------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
addItemToDocumentGrid();
$('#removeDocumentFromSection').disable(true).addClass("disabled");
$('#removeSelection').disable(true).addClass("disabled");
});
If you don't want to use event delegation, you need to call on on the element you want to hook the event on:
$('#' + GlobalVariables.currentUserType).find(".addDocumentToSection").on("click", function (e) {
addItemToDocumentGrid();
$('#removeDocumentFromSection').disable(true).addClass("disabled");
$('#removeSelection').disable(true).addClass("disabled");
});
This is all covered in the on documentation.
You are attaching onClick event to a document element. Try:
var button = $('#' + GlobalVariables.currentUserType).find(".addDocumentToSection");
button.on("click", function() {
addItemToDocumentGrid();
$('#removeDocumentFromSection').disable(true).addClass("disabled");
$('#removeSelection').disable(true).addClass("disabled");
});
$('#' + GlobalVariables.currentUserType).find(".addDocumentToSection").on("click", function(e){
});
jQuery can use selectors before the .on("click", this should work for you.

After appending an element the event click is not working on the appended element in jQuery

I am appending item by jQuery. But after appending can't bind the event on the appended item. I am appending as follows:
var item = '<div id="'+newInputId+'" class="col-md-9" style="padding-right: 0px;">';
item += '<input id="txtInScope" type="text" value="'+currentScopeVal+'" class="form-control" readonly="readonly"/>';
item += '</div>';
item += '<div id="inScopeActionDiv'+newInputId+'" class="col-md-3" style="padding-left: 2px;">';
item += '<button type="button" class="btn btn-warning btn-sm remButton" title="Remove this item">Remove Item</button>';
item += '</div>';
$('#inScopeDiv').append(item);
And after appending this I want to bind a click event on the above remButton class as below:
$("#inScopeDiv").delegate(".remButton", "click", function(){
alert('you clicked me again!');
});
$('#inScopeDiv').on('click', '.remButton', function() {
alert("working");
})
$('.remButton').live('click', function() {
alert('live');
})
But no result. What can I try next?
$('.remButton').live('click', function() {
alert('live');
})
jquery method live is not valid anymore:
"As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live()."
Source: jquery live
Little explanation about event attachment:
You must realize that a target what you want to add a event, exists BEFORE to call the add event function(in this case with the method on of jQuery).
on another hand, exists with jquery a manner to make work a event attachment without the existence of the element before:
$('html').on('click', '#inScopeDiv .remButton', function () {
alert('works!');
});
Bind it on a parent that is not dynamic but always in the DOM.
You need to add the listener each time you add an item:
$('#inScopeDiv').append(item)
.off() //unbind old listeners so no duplicate listeners
.on('click', '.remButton', function() {
alert("working");
});
You could store the appended div in a variable using .appendTo and then you could attach the click event directly to the variable. See it working: JSFiddle
$(".appendDiv").click(function () {
var item = "<div>I'm a new div!</div>";
var appended_div = $(item).appendTo(".container");
appended_div.click(function () {
alert("Working!");
});
});

Dont understand why .remove() not working [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
Hi I am learning jQuery and I do not understand why this fucntion does not work. When I click the button it should remove the div but it does not.
The remove function
$(".editButton").click(function () {
$(".editButton").remove();
});
Function that creates the div
var formatPost = function (d) {
var s = '';
s = '<div class="post" data-id="' + d.id + '"><h2 class="postHeading">' + d.title + '</h2>';
s += d.body;
s += '<p> Posted on: ' + d.date + '</p>';
s += '<div class="btn editButton">Edit Post</div>'
s += '</div>'
return s;
};
Currently you are using direct binding, this works when the element exist on the page at the time your code makes the event binding call.
You need to use Event Delegation using .on() delegated-events approach.
i.e.
$(document).on('event','selector',callback_function)
Use,
If you want to remove only button
$(document).on('click', '.editButton', function () {
$(this).remove();
});
If you want to remove complete post, First, You need to execute the action in current element context so use this.
Then use closest() to find post parent and then use .remove()
$(document).on('click', '.editButton', function () {
$(this).closest('.post').remove();
});
Since you are dynamically creating div, use event delegation
$(document).on('click', '.editButton', function () {
$(this).remove();
});
Use Event Delegation.
You added the edit button dynamically. DOM didn't know when was the element is added so we need to traverse from the document or the body or Immediate parent selector to find the element
$(document).on('click', '.editButton', function () {
$(this).remove();
});

a href click not triggering in jquery

$(function() {
$.getJSON("companies.json", function(response) {
var html = '<table id="tbl">';
response.businesses.forEach(function(row) {
html += '<tr><td>' + row.id + '</td><td>' + row.name;
});
html += '</table>';
$("#tabledata").html(html);
});
$(".move").click(function() {
var $id = $(this).attr("idname");
$.getJSON("companies.json", function(response) {
$.map(response.businesses, function(obj) {
if (obj.id == $id)
console.log(obj);
return obj; // or return obj.name, whatever.
});
});
});
});
HTML:
<div id="tabledata" class='left'></div>
<div class="right"></div>
Please help?
As your .move element is added to your page dynamically, you have to make use of jQuery's on() method to delegate the event to an ancestor of the .move element which does exist when your JavaScript first loads.
$(document).on('click', '.move', function() { ... });
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
You can read more about jQuery's event delegation here.
If you use event delegation, your problem goes away (and your app becomes more performant and less prone to memory leaks).
// Only do this once, when your page loads...
$(document.body).on('click', '.move', function (ev) {
// This is the link that was clicked.
var $targ = $(ev.target);
});
Try This
$('#tabledata').on('click', '.move', function(e) { ... });
The reason the event isn't being triggered is because the event is only added to elements that exist on the page when you call the .click() method.
Instead, you can use event delegation:
$(document.body).on('click', '.move', function (ev) {
var $targ = $(ev.target);
});
which really says: call the function when any element that matches .move that's inside document.body is clicked.
I know others have said this already but I wanted to make event delegation clearer.

Categories