2

I want to delete some data displayed in a HTML table row (first on the database and then remove from the HTML table). I have added a delete link to each HTML table row, and when this link is clicked, I want first to make a jQuery $.get to update the database, and if that returns successful, then I want to remove the HTML row. I have gotten each part working successfully separately, but when I try to combine them, I run into trouble. When combined, the part that makes the AJAX call to update the database works, but not the part that does the $(this).remove(). I can see that, at the moment of calling $(this).remove(), the value of $(this) is referring to the $.get, when I know I need it to be referring to ".delete_link". But I don't see how I can change that. Clearly I'm struggling with some of the fundamentals of jQuery. I tried breaking each part up into component functions, but that seemed to make things even worse.

  $(document).ready(function() {
    $(".delete_link").click(function () {
      if (confirm('Are you sure???')) {
        $.get("/comments/ajax-delete-comment?comment_id=4220537", function(response) {
            if (response == 1) {
              alert("Couldn't update database");
            } else {
              $(this).closest('tr').fadeTo(400, 0, function () {
                $(this).remove();
              });
            }
        });


        return false;
      }
      return false;
    });
  });
TrojanName
  • 4,853
  • 5
  • 29
  • 41
  • 1
    Aside: You may want to use the `data` option/parameter with `$.get` instead of using a query string in the URL. – Evan Mulawski Mar 22 '12 at 18:52
  • 1
    Inside the callback, `this` is different to what it is outside. – Orbling Mar 22 '12 at 18:53
  • 2
    Exact duplicate of [$(this) doesn't work in a function](http://stackoverflow.com/questions/7859558/this-doesnt-work-in-a-function) - This question has been asked over a zillion times. – Rob W Mar 22 '12 at 18:53
  • 1
    Set `var cLink = $(this);` before the `$.get()` call, and use `cLink.closest(...)` and `cLink.remove();` inside the callback. – Orbling Mar 22 '12 at 18:54
  • @RobW believe me, I searched. Knowing the right keywords is part of the solution. I'm not one to idly ask questions or waste people's time. – TrojanName Mar 22 '12 at 19:07
  • @EvanMulawski - thanks for that, much appreciated. Any other general tips would be greatly appreciated too! :-) – TrojanName Mar 22 '12 at 19:09

5 Answers5

4

Simply capture this in a variable.

if (confirm('Are you sure???')) {
    var that = $(this);
    $.get("/comments/ajax-delete-comment?comment_id=4220537", function(response) {
        if (response == 1) {
            alert("Couldn't update database");
        } else {
            that.closest('tr').fadeTo(400, 0, function() {
                $(this).remove();
            });
        }
    });


    return false;
}​
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
  • Thanks. I notice you have kept the $(this).remove() - why is that? – TrojanName Mar 22 '12 at 19:11
  • You're welcome! Doesn't really make a difference, but for me it helps to remind me about the scope of the callback to `fadeTo` in this instance. – Chris Laplante Mar 22 '12 at 19:12
  • Right, I'm kind of confused though. Has $(this) somehow gotten reassigned the right value? – TrojanName Mar 22 '12 at 19:22
  • 1
    Yes! :) Once you call `fadeTo`, `this` inside its callback automatically refers to the element that your chain is operating on; the default behavior for jQuery chains. – Chris Laplante Mar 22 '12 at 19:23
  • Oh man, that is confusing. Any links to articles/explanations? I'm accepting your answer, by the way. – TrojanName Mar 22 '12 at 19:27
  • Once you get it, it will become easy and a great way to program. But yes, it was initially confusing to learn. I can't think of any articles, but I was looking on Amazon and this looks like a helpful book: http://www.amazon.com/jQuery-Cookbook-Solutions-Examples-Developers/dp/0596159773/ref=sr_1_1?ie=UTF8&qid=1332444668&sr=8-1 , specifically chapter 5. – Chris Laplante Mar 22 '12 at 19:31
  • 1
    Actually, check out this article: http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx – Chris Laplante Mar 22 '12 at 19:33
  • Thanks. Much appreciated. I still can't get over that my question was answered in 1 minute, when I spent all evening trying to figure it out! Hahaha! – TrojanName Mar 22 '12 at 19:53
  • Don't feel bad! It's a common problem that we see here frequently (hence why it was answered by four people in 1 minute) :). Consider it a logical pitfall to make for anyone learning jQuery. – Chris Laplante Mar 22 '12 at 19:56
2

You should store $(this) in a variable:

$(document).ready(function() {
    $(".delete_link").click(function () {
      if (confirm('Are you sure???')) {

        var $link = $(this);

        $.get("/comments/ajax-delete-comment?comment_id=4220537", function(response) {
            // THIS in this context is jQuery not the link you want

            if (response == 1) {
              alert("Couldn't update database");
            } else {
              $link.closest('tr').fadeTo(400, 0, function () {
                $link.remove();
              });
            }
        });


        return false;
      }
      return false;
    });
});
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
max
  • 96,212
  • 14
  • 104
  • 165
  • 2
    You should really do `var $link = $(this)`. – gen_Eric Mar 22 '12 at 18:54
  • Thanks for this. Initially I thought your answer was the same as SimpleCoder's but I see that you have a $ in front of the variable, where he/she has just a "that". Are they both correct solutions? – TrojanName Mar 22 '12 at 19:13
  • 1
    yes, the $ is just a programmer convention. It makes it easier to see that the variable is jQuery object. Javascript does´nt care what you name your variables. – max Mar 22 '12 at 19:16
2

try caching this on click

 $(document).ready(function() {
    $(".delete_link").click(function () {
      var $this=$(this);
      if (confirm('Are you sure???')) {
        $.get("/comments/ajax-delete-comment?comment_id=4220537", function(response) {
            if (response == 1) {
              alert("Couldn't update database");
            } else {
              $this.closest('tr').fadeTo(400, 0, function () {
                $this.remove();
              });
            }
        });


        return false;
      }
      return false;
    });
  });
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
Rafay
  • 30,950
  • 5
  • 68
  • 101
  • 1
    You should really do `var $this = $(this);` – gen_Eric Mar 22 '12 at 18:55
  • Thanks for this. Initially I thought your answer was the same as SimpleCoder's but I see that you have a $ in front of the variable, where he/she has just a "that". Are they both correct solutions? – TrojanName Mar 22 '12 at 19:12
  • @BrianFenton yes both were the same solutions `var $this` and `var that` are the same things – Rafay Mar 22 '12 at 21:03
1
  $(document).ready(function() {
    $(".delete_link").click(function () {
      var delIndex = $(this).index();

      if (confirm('Are you sure???')) {
        $.get("/comments/ajax-delete-comment?comment_id=4220537", function(response) {
            if (response == 1) {
              alert("Couldn't update database");
            } else {
              $('.delete_link').eq(delIndex).closest('tr').fadeTo(400, 0, function () {
                $('.delete_link').eq(delIndex).remove();
              });
            }
        });


        return false;
      }
      return false;
    });
  });
Gabriel Santos
  • 4,934
  • 2
  • 43
  • 74
1

Inside the $.get callback, this is no longer your element.

You need to save this as a variable before $.get.

var that = this;
$.get(url, function(){
    $(that).closest('tr') // 'that' will be the correct element
});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337