1

This is something I've needed to learn for a while and I'm wondering if any javascript experts can point me in the right direction.

Many libraries I've used seem to accept function pointers as arguments, such as a hook for success, fail, etc. Here is a simple example of this in an application I'm working on:

$('.clock-btn').each(function(){
$(this).click(function(){
    $.ajax(
        {
            url:'punch.php?task_id=' + $(this).data('task-id'),
            success: function() {
                reverseCSS($(this));
            },
            error: function() {
                window.alert("Clocking time to this project is not allowed.");
            }
        }
    );
});

});

Where the reverseCSS() function is a function that will change the button to an animation and exchange the words with 'clock-in/clock-out' depending on what it was previously.

However, I cannot gain access to the $(this) variable in the $.ajax call. This is expected behavior to me, as I know in this example, the $(this) will be the $.ajax object, not the item I need from the html.

So, what would be the best method here to access the $(this) item?

Thanks so much for your help.

smnbbrv
  • 23,502
  • 9
  • 78
  • 109
dmcmulle
  • 339
  • 3
  • 11
  • 2
    Add a variable before your ajax call : var mythis = $(this) and pass mythis to function – Zaki Aug 18 '15 at 15:47
  • By the way , you can still optimize your code by replacing the double close with a single with `$('.clock-btn').click(function()....` – albanx Aug 18 '15 at 15:59

3 Answers3

4

This is what bind() function does:

$('.clock-btn').each(function(){
$(this).click(function(){
    $.ajax(
        {
            url:'punch.php?task_id=' + $(this).data('task-id'),
            success: function() {
                reverseCSS($(this));
            }.bind(this)
        }
    );
});

it simply returns a function which is always running in a context you give it, in this case the context is this

smnbbrv
  • 23,502
  • 9
  • 78
  • 109
  • This should be the correct answer. – Jan Aug 18 '15 at 15:51
  • Ah, the bind method! I've seen this in places but never took the effort to read more about it. Thank you so much! – dmcmulle Aug 18 '15 at 15:59
  • you are welcome, in ES6 it is even going to be way easier with so called arrow functions, see e.g. here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions – smnbbrv Aug 18 '15 at 16:02
  • the bind method is not compatible with the some old browser . – albanx Aug 18 '15 at 16:05
  • Although you are talking about ancient browsers which nobody supports, you can always use polyfill, e.g. see here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/bind – smnbbrv Aug 18 '15 at 16:08
  • @simon Yes, you are right. Today does not worth supporting old browser like IE, most web technologies are focus on modern features – albanx Aug 19 '15 at 12:47
1

Something along the lines of:

$(this).click(function() {
  var $self = $(this);

  $.ajax({
    url:'punch.php?task_id=' + $(this).data('task-id'),
      success: function() {
        reverseCSS($self);
      },

      // ...
jdlm
  • 6,327
  • 5
  • 29
  • 49
  • This is a useful answer, and I probably should have stated that I am trying to find out how to access it without creating temporary variables. Hopefully this helps someone else, though! – dmcmulle Aug 18 '15 at 16:00
0
$('.clock-btn').each(function(){
    $(this).click(function(){
        var that = this; // save it to another variable
        $.ajax({
            url:'punch.php?task_id=' + $(this).data('task-id'),
            success: function() {
                reverseCSS($(that));
            },
            error: function() {
                window.alert("Clocking time to this project is not allowed.");
            }
        });
    });
});
Jan
  • 42,290
  • 8
  • 54
  • 79