$('.icn-trash').on('click', function(e) {
e.preventDefault();
deleteBookmark($('.del').data('bookmarkid'));
});
function deleteBookmark(bookmarkID) {
$.ajax({
url: '/BookmarkApi/delete/' + bookmarkID,
type: 'POST',
success: function(response) {
$('.icn-trash').closest('.del').remove();
console.log('removed');
},
error: function(error) {
}
});
}
HTML - it will be generated dynamically for every bookmark folder.
<a href="#" class="del" data-bookmarkid="xxx">
<span class="actions" style="z-index:300">
<i class="icn-trash"></i>
</span>
</a>
Everytime, I try to delete the specific id of the bookmark folder, multiple folders are removed. It should only remove one specific folder when clicking trash icon. When I clicked trash icon on 6th folder, the 1st, 2nd, 3rd, 4th, 5th folders will disappear and i refreshed again only to find 1st folder actually being removed from database.
I want to have 6th folder disappear and removed from database.
Help appreciated.
Try this way
$(document).on('click', '.icn-trash',function(evt) {
evt.preventDefault();
var b_id=$(this).closest('.del').data('bookmarkid')
$.ajax({
url: '/BookmarkApi/delete/' + b_id,
type: 'POST',
success: function(response) {
$(this).closest('.del').remove();
console.log('removed');
},
error: function(error) {
}
});
});
I would bind the event on the a tag:
$('.del').on('click', function(e) {
e.preventDefault();
deleteBookmark(this);
});
function deleteBookmark(ele) {
$.ajax({
url: '/BookmarkApi/delete/' + $(ele).data('bookmarkid'),
type: 'POST',
success: function(response) {
$(ele).remove();
console.log('removed');
},
error: function(error) {
}
});
}
Or if you still want to bind on .icn-trash:
$('.icn-trash').on('click', function(e) {
e.preventDefault();
deleteBookmark($(this).closest('.del'));
});
function deleteBookmark(ele) {
$.ajax({
url: '/BookmarkApi/delete/' + ele.data('bookmarkid'),
type: 'POST',
success: function(response) {
ele.remove();
console.log('removed');
},
error: function(error) {
}
});
}
You are removing content using class attribute that return collection of all the links and remove the links.
$('.icn-trash').on('click', function (e) {
debugger
event.preventDefault()
deleteBookmark(this);
});
function deleteBookmark(obj) {
debugger
bookmarkID = $('.del').data('bookmarkid');
$(obj).remove();
$.ajax({
url: '/BookmarkApi/delete ,
data: { bookmarkID: bookmarkID},
type: 'POST',
success: function (response) {
console.log('removed');
},
error: function (error) {
}
});
}
From the jQuery Documentation of closest API
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
Now what is happening in the code $('.icn-trash').closest('.del').remove();
$(.icn-trash') is returning the set of all element elements having the class icn-trash. And then you are using this set to find the closest element with class .del which will return a set of all anchor tags (in your html example). Finally you are removing the entire set. Hence multiple bookmarks are getting deleted.
I am assuming you need to delete the anchor tag which has the data-bookmarkid as bookmarkID
$('.icn-trash').on('click', function(e) {
e.preventDefault();
deleteBookmark($('.del').data('bookmarkid'));
});
function deleteBookmark(bookmarkID) {
$.ajax({
url: '/BookmarkApi/delete/' + bookmarkID,
type: 'POST',
success: function(response) {
// get the element with data-bookmarkid = bookmarkID and remove it
$("[data-bookmarkid='" + bookmarkID + "']").remove()
console.log('removed');
},
error: function(error) {
}
});
}
EDIT: I didn't read the last part of your question
When I clicked trash icon on 6th folder, the 1st, 2nd, 3rd, 4th, 5th folders will disappear and i refreshed again only to find 1st folder actually being removed from database.
Can you make sure that the bookmarkIds are correct in the data-bookmarkid attribute? Since clicking on 6th trash icon is removing the 1st folder from the database, there seems to be a problem either with your server code or the data-bookmarkid attribute is incorrect in the 6th trash icon
EDIT2: Why you are getting the wrong bookmarkId (Didn't investigat enough thoroughly earlier, got involved in something else)
Again quoting from jQuery documentation for data API
Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute.
So analyzing your code deleteBookMark($('.del').data('bookmarkid')): $('.del') will contain all the elements with class name del (in your example all the anchor tags). Calling .data('bookmarkid') with the entire set will return the bookmark id of the first anchor tag. The best way to do this is to first obtain the element which was clicked. This can be done by modifying your code
Again from jQuery Documentation for Event Listener
When jQuery calls a handler, the this keyword is a reference to the element where the event is being delivered;...
To create a jQuery object from the element so that it can be used with jQuery methods, use $( this ).
This means that
$('.icn-trash').on('click', function(e) {
e.preventDefault();
deleteBookmark($('.del').data('bookmarkid'));
});
In the listener you have attached, this will refer to the .icn-trash element you clicked on. So now you know which element was clicked, find the closest .del element and then get its data-bookmarkid attribute. i.e.
$('.icn-trash').on('click', function(e) {
e.preventDefault();
var curIconTrash = $(this),
closestAnchor = curIconTrash.closest('.del'),
bookMarkId = closestAnchor.data('bookmarkid')
deleteBookmark(bookmarkId);
});
Or taking the advantage of jQuery chaining
$('.icn-trash').on('click', function(e) {
e.preventDefault();
deleteBookmark($(this).closest('.del').data('bookmarkid'));
});
Note: This was also suggested by #sreedhar-r
Hope this helps! Cheers :-)
Related
So, I have a jQuery AJAX call that gets data from the server (some text, some links).
Inside AJAX success callback function I got a .on that is bind to <a> that load for me next page and get me the text of the clicked link (let's say stackoverflow.com).
The problem starts here because in the newly loaded page I got anchors...
After every click on anchor links I got new .text() value.
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data){
$('.container').append(data);
$('.container').on('click', 'a', function(e){
e.preventDefault();
var clickLinkName = $(this).text();
console.log(clickLinkName);
$('.container').load($(this).attr('href'));
});
}
});
I would like to know how to lock clickLinkName variable. OR any other way to save only first hit.
I think this would do the trick:
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data) {
$(".container").append(data);
var clickLinkName; // Declared here.
$(".container").on("click", "a", function(e) {
e.preventDefault();
// If not initialized, initialize.
if(!clickLinkName) {
clickLinkName = $(this).text();
}
console.log(clickLinkName);
$(".container").load($(this).attr("href"));
});
}
});
That would save only the first value in the variable clickLinkName. This answers your question, but I'm sure there are better ways of doing this.
I'm using below code. This is bootstrap 3 delete conformation message.
$(document).ready(function(){
$('a.btnDelete').on('click', function (e) {
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
$('#btnDelteYes').click(function () {
var id = $('#myModal').data('id');
var dataString = 'id='+ id ;
$('[data-id=' + id + ']').parent().remove();
$('#myModal').modal('hide');
//ajax
$.ajax({
type: "POST",
url: "delete.php",
data: dataString,
cache: false,
success: function(html)
{
//$(".fav-count").html(html);
$("#output").html(html);
}
});
//ajax ends
});
});
This is the trigger element that I'm using
<div data-id="MYID"><a class="btnDelete" href="#">Delete</a></div>
And I'm using the same HTML element dynamically to trigger delete and it doesn't work.
Can someone point me the correct way to do it?
You have to use event delegation
$(document).on("click" , '#btnDelteYes' ,function () {
Pretty much: bind the click higher up to something that exists when the script is run, and when that something is clicked, tell it to pass the click event to the #btnDelteYes element instead
I cant understand what exactly you are doing on your code due to missing information, but the answer is: you should use event delegation on the dynamically inserted content
you can try
$('[data-id=MYID]').on('click','.btnDelteYes',function({
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
here <div data-id="MYID"> should be a hard coded html content and The idea is to delegate the events to that wrapper, instead of binding handlers directly on the dynamic elements.
I have a Jquery function to delete a row in an HTML table, it looks like this;
$(document).ready(function(){
$("#thisNet td a.delete").click(function() {
if (confirm("Are you sure you want to delete this row?")) {
var id = $(this).parent().parent().attr('id');
var data = 'id=' + id ;
var parent = $(this).parent().parent();
$.ajax({
type: "POST",
url: "delete-row.php",
data: data,
cache: false,
success: function()
{
parent.fadeOut('slow', function() {$(this).remove();});
}
});
}
});
});
I don't know if it works or not because when I click the button I never get into the function. The delete item to click is in a table created by PHP/MySQL. I followed the tutorial here; https://sarfraznawaz.wordpress.com/2009/09/14/deleting-table-rows-using-jquery-and-php/ to create the delete function. I'm guessing the reason it doesn't fire has to do with timing. The $(document).ready(function() already thinks the page is done loading before the table is created..but I don't know how to overcome this problem.
The page is here; http://kcmecc.org/RaspPi/ once you access it use the drop down to select Net #1. The delete column is the last one with the red x.
Your delete button doesn't exist on document ready. You need to use .on to delegate the event to an ancestor element when dynamically adding elements...
$(document).on('click', '#thisNet td a.delete', function() {
This code works fine for first click as it changes class along with image which is referenced from CSS. But when I click second time it acts like clicked in previous class which I assume removed already.
if(Model.SeenItWantToSeeIt.Status==1)
{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
else{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
And Javascript for toggling class is
$(".want_to_see_it").click(function () {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 1, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$("dont_want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
$(".dont_want_to_see_it").click(function () {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 0, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$("want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
And problem is it shows "clicked on donot want to see it" or "clicked on want to see it" as alert every time I click . What I have to do is this message should alternate every time I Click on their respective image.
Problem here is that you want to change the handlers dynamically on click of each element. But events are bound to the element directly using click event.
One option is to hide and show respective items.
Another option is to bind and unbind events.
Third option is to use event delegation. Your requirement will work with this since with event delegation events are not directly attached to the elements, they are instead delegated. So the moment you swap the class name event subscribed for that class name will automatically get delegated. SO next click on the same element will go to the other event handler attached its new class name. See if this is what you were looking for.
$(document).on('click',".want_to_see_it" ,function (e) {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$(".dont_want_to_see_it").show();
});
$(document).on('click',".dont_want_to_see_it" ,function (e) {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$(".want_to_see_it").show();
});
Note:- In the example i have attached to the document, You should n't attach it to the document, instead attach it to any containing element that is present in DOM at any time.
Demo
There was another issue, you missed . before the classname in your ajax success.
The problem is you need to unbind("click") to clear the previous handler then bind a new event handler for its new class.
Instead of unbinding and rebinding, do in one handler:
$(".usermovie_option a").on("click", function () {
var status = 0;
if ($(this).hasClass("want_to_see_it")) {
status = 1;
}
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: status, MovieID: movieID,
dataType: 'json',
type: "POST",
success: function (data) {
$(this).toggleClass("want_to_see_it");
$(this).toggleClass("dont_want_to_see_it");
},
error: function (data) {
alert('Error occurred.');
}
});
});
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
$(this) doesn't work in a function
Im having a problem targeting the right element in my code. I have a list of thumbnails on my page, and when you click on a "I dislike this" icon the targeted video change for another one.
Here's the HTML
<li class="videoBox recommended">
<div class="spacer" style="display: block;"></div>
<div class="features">
<div>
<a class="dislike_black" title="I dislike this" onclick="ThumbsDown(30835, 'relevance', '1');"></a>
</div>
</div>
<a href="...">
<h1>...</h1>
<div class="information">...</div>
</li>
Ajax is:
function ThumbsDown(id,sort,page) {
$.ajax({
url: "/change/videos/"+id+"/thumbsdown/",
type: "POST",
data: {
"sort": sort?sort:"",
"page": page?page:""
},
success: function(data) {
//$("#content .videoList ul li.videoBox").html(data); // THIS IS WORKING, but replaces ALL the divs
$(this).parent("li.videoBox").html(data); // Cant get this to work!
}
});
What Iam doing wrong? even $(this).css("border","1px solid red") is not "working". (I tried with background color, and color too) I dont see anything.
$(This) refers to the "a" tag where the function is called right? So im searching for his parent named videobox... Help?
So can I target
You should not use onclick, you should bind it to an event, especially as you could easily make this degrade well if the user does not have ajax.
Change your <a> tags to this:
<a href="/change/videos/1/thumbsdown/"
data-sort="sort"
data-page="page"
class="dislike_black"
title="I dislike this"></a>
jQuery event:
$('.dislike_black').click(function(e) {
e.preventDefault(); // Prevent link from clicking
var $aTag = $(this); // I use $aTag to denote a jq object
$.ajax({
url: $aTag.attr('href'),
type: "POST",
data: {
"sort": $aTag.data('sort'), // data-sort attr value
"page": $aTag.data('page') // data-page attr value
},
success: function(response) {
$aTag.closest(".videoBox").html(response);
}
});
});
Now it works without javascript, and you're not using nasty onclick! Untested/no warranty.
Almost. In order to make this work, you need to pass in the context to the .ajax() call.
Like
$.ajax({
url: "/change/videos/"+id+"/thumbsdown/",
type: "POST",
context: document.body, // for instance
data: {
"sort": sort?sort:"",
"page": page?page:""
},
success: function(data) {
//$("#content .videoList ul li.videoBox").html(data); // THIS IS WORKING, but replaces ALL the divs
$(this).parent("li.videoBox").html(data); // Cant get this to work!
}
});
The above code would cause that all ajax handlers will have this pointing to document.body. So you would need to replace the document.body with the element you are looking for. So, if you for instance call your function in some kind of a click handler you could just call context: this and the magic is done.
See jQuery Ajax Doc section "context" for more details.
I believe all you needed to change in your original code was to get the reference to this outside of the success function, like this:
function ThumbsDown(id,sort,page) {
var self = this
$.ajax({
url: "/change/videos/"+id+"/thumbsdown/",
type: "POST",
data: {
"sort": sort?sort:"",
"page": page?page:""
},
success: function(data) {
//$("#content .videoList ul li.videoBox").html(data); // THIS IS WORKING, but replaces ALL the divs
$(self).parent("li.videoBox").html(data); // Cant get this to work!
}
});