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

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();
});

Related

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!");
});
});

jQuery `.parent().remove()` is not working

The solution may be obvious, but when clicking the .remove element, I am trying to remove the entire .tag element that is the parent. Currently, clicking the .remove element has no response.
HTML
'<div class="tag"><input id="' + id + '" type="hidden" name="' + name + '" value="' + value + '" />' + input + '<i class="remove dismiss fa fa-remove"></i></div>'
JS
$('.remove').on('click', '.remove', function() {
$(this).parent().remove();
});
Try this : As you are adding remove link dynamically, you need to register click handler using .on(). But in your case you have error in using .on(). Please use below code.
$(document).on('click', '.remove', function() {
$(this).parent().remove();
});
More Information on jQuery .on()
You can try this:
http://jsfiddle.net/myyzrwwe/
$('.remove').on('click', function() {
$(this).parent().remove();
});
You shouldn't always use delegate the event to the same element that has been delegated. You need to select a static parent. In my example, the document object is the parent of everything.
$('body').on('click', '.remove', function() {
$(this).parent().remove();
});
The problem might be you are binding the event to .remove, if this content is dynamic you might have a problem. Its better, in those cases, to bind to document.
$(document).on()
The callback has the event parameter, use that to remove.
function(e) {
$(e.currentTarget).parent().remove();
}
Check if you undelegate elements.

jquery: how to add event handler to dynamically added element without adding it to existing element again

I'll try to explain my problem:
I have a website where the user dynamically adds elements. They all belong to the "toBuy" class. Whenever a new element is added to this class I need to attach a click-handler to only this element but not to all others. To keep my code clean I want to have a function that does this work. Here is what i've tried:
this is how the stuff is added:
$("#addItemButton").click(function(){
var item= $('#item').val();
$('#item').val("");
var quantity= $('#quantity').val();
$('#quantity').val("");
var comment=$('#addComment').val();
$('#addComment').val("");
//construct new html
var newitem="<div class='toBuyItem'><div class='item'>";
newitem+=item;
newitem+="</div><div class='quantity'>";
newitem+=quantity;
newitem+="</div><div class='comment'><img src='img/comment";
if(comment==""){
newitem+="_none"
}
newitem+=".png' alt='Comment'></div><div class='itemComment'>"
newitem+=comment;
newitem+="</div></div>";
$("#toBuyItems" ).prepend( newitem );
toggle("#addItemClicked");
initializeEventListeners();
});
then this is the initializeEventListeners function (which I also run when the page loads so that the existing elements have the event handlers already:
function initializeEventListeners(){
$(".toBuyItem").click(function(){
console.log($(this).html());
console.log($(this).has('.itemComment').length);
if($(this).has('.itemComment').length != 0){
console.log("toggling");
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
});
}
function toggle(item){
$( item ).slideToggle(500);
}
now apparently what happens is that when a new element is added the existing elements get a new event handler for clicking (so they have it twice). Meaning that they toggle on and off with just one click. Probably it's damn simple but I cannot wrap my head around it....
EDIT:
so this works:
$(document).on('click', '.toBuyItem', function(){
if($(this).has('.itemComment').length != 0){
console.log("toggling");
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
});
Use jquery's on method. This way you have to add event only once. This will be added automatically to dynamically added elements.
$(document/parentSelector).on('click', '.toBuyItem', function() {
// Event handler code here
});
If you are using parentSelector in the above syntax, it has to be present at the time of adding event.
Docs: https://api.jquery.com/on
You can use jQuery.on method. It can attach handlers to all existing in the DOM and created in future tags of the selector. Syntax is as follows:
$(document).on('click', '.toBuyItem', function(){
//do onClick stuff
})
As others have suggested, you can delegate click handling to document or some suitable container element, and that's probably what I would do.
But you could alternatively define a named click handler, which would be available to be attached to elements already present on page load, and (scope permitting) to elements added later.
You might choose to write ...
function buy() {
if($(this).has('.itemComment').length != 0) {
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
}
function initializeEventListeners() {
$(".toBuyItem").on('click', buy);
}
$("#addItemButton").on('click', function() {
var item = $('#item').val(),
quantity = $('#quantity').val(),
comment = $('#addComment').val();
$('#item', '#quantity', '#addComment').val("");
//construct and append a new item
var $newitem = $('<div class="toBuyItem"><div class="item">' + item + '</div><div class="quantity">' + quantity + '</div><div class="comment"><img alt="Comment"></div><div class="itemComment">' + comment + '</div></div>').prependTo("#toBuyItems").on('click', buy);// <<<<< here, you benefit from having named the click handler
$newitem.find(".comment img").attr('src', comment ? 'img/comment.png' : 'img/comment_none.png');
toggle("#addItemClicked");
});

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.

How to remove an element that is added dynamically in Javascript

I have the following code to create some element:
<div id="parent">
<div id="block_1" >
<div>
<input type="text">
</div>
<img src="arrow.jpg">
<div>
<input type="text">
</div>
<div>Remove</div>
</div>
</div>
the result look like this:
When user presses the ADD button it will go to a Javascript function and create the same block of div. Here is the code:
function add_block() {
var curDiv = $('#parent');
var i = $('#parent div').size()/4 + 1;
var newDiv='<div id="block_'+ i + '" class="parent_div">' +
'<div>' +
'<input type="text">' +
'</div>' +
'<img src="arrow.jpg">' +
'<div>' +
'<input type="text">' +
'</div><div><a class="remove_block" href="#">Remove</a></div>' +
'</div>';
$(newDiv).appendTo(curDiv);
};
Whenever the user press the "Remove" link on the left hand side of the block, that corresponding block should be removed. And this is what I did:
$('a.remove_block').on('click',function(events){
$(this).parents('div').eq(1).remove();
});
The problem is that only the remove in the original block work, the rest didn't . Anybody know why?
I am new to jQuery and Javascript, so I really appreciate any help and suggestion
Note: I use jQuery 2.0.3
Because it's dynamic content, you can't bind events like the static content, it will not bind to the elements because they don't appear at the time you bind.
So you should bind event like this:
$('#parent').on('click', 'a.remove_block', function(events){
$(this).parents('div').eq(1).remove();
});
You need to use event delegation for dynamically added elements. Even though you have used .on() the syntax used does not use event delegation.
When you register a normal event it adds the handler to only those elements which exists in the dom at that point of time, but when uses event delegation the handler is registered to a element which exists at the time of execution and the passed selector is evaluated when the event is bubbled upto the element
$(document).on('click', '.remove_block', function(events){
$(this).parents('div').eq(1).remove();
});
$('a.remove_block').on('click',function(events){
$(this).parents('.parent_div').remove();
return false;
});
I had the situation where the dynamic element to remove wasn't a descendant of my event listener:
siteSel.on('select2:select', function (e) {
// remove some other dynamic element on page.
});
Solution I found was using when() method.
siteSel.on('select2:select', function (e) {
let dynamicElement = $('.element');
$.when(dynamicElement).then(dynamicElement.remove());
});
You can use the .live for this:
$('body').live('click','#idDinamicElement', function(){
// your code here
});

Categories