0

I have an onclick event that passes a $(this) argument to a function.

<tr class="myTr">
  <td>
    Han Solo
  </td>
</tr>  

<script>
$('body').on('click','.myTr',function(){
  doSomething($(this));
});
</script>

Now, I want to add another step. I want to show a button, and after this button is click, doSomething() is supposed to be called.

<tr class="myTr">
  <td>
    Han Solo
  </td>
</tr>  
<button id="myBtn" style="display:none">Submit</button>

<script>
  $('body').on('click','.myTr',function(){
    $('#myBtn').show();
  });
  $('#myBtn').click(function(){
    doSomething(???);
  });
</script>

How do I pass the $(this) to the second click event?

I could easily store the $(this)as a tag of the button, something like this:

$('body').on('click','.myTr',function(){
  $('#myBtn').attr('origin', $(this));
  $('#myBtn').show();
});
$('#myBtn').click(function(){
  var tr = $(this)attr('origin');
  doSomething(tr);
});

But I was wondering if there is a more elegant way to solve this?

7
  • 1
    Use a data attribute instead of attr. $('#myBtn').data('origin', $(this)); and $(this).data('origin'); Commented Apr 11, 2017 at 21:36
  • 1
    use global variables? Commented Apr 11, 2017 at 21:37
  • 1
    other option is to unbind and rebind it the click event, updating the script to use the variable with a closure. I would use the data attr. Commented Apr 11, 2017 at 21:38
  • 1
    Well you need to store it somewhere... Commented Apr 11, 2017 at 21:40
  • 1
    The possible solutions are listed.... Commented Apr 11, 2017 at 21:41

2 Answers 2

1

You need to set the state in some manner

Data attribute:

$('body').on('click','.myTr',function(){
  $('#myBtn').data('origin', $(this)).show();
});
$('#myBtn').click(function(){
  var tr = $(this).data('origin');
  doSomething(tr);
});

Local Variable

(function () {
    var active;
    $('body').on('click','.myTr',function(){
      active = $(this);
      $('#myBtn').show();
    });
    $('#myBtn').click(function(){      
      doSomething(active);
    });
}());

Rebind the event:

$('body').on('click','.myTr',function(){
  var active = $(this);
  $('#myBtn')
    .off("click.tr")
    .on("click.tr", function () {
      doSomething(active);
    })
    .show();
});

CSS class:

$('body').on('click','.myTr',function(){
  $(".myTr.active").removeClass("active");
  $(this).addClass("active");
  $('#myBtn').show();
});
$('#myBtn').click(function(){
  var tr = $(".myTr.active");
  doSomething(tr);
});
Sign up to request clarification or add additional context in comments.

Comments

1

Simply use $.proxy from jQuery

$('body').on('click','.myTr',function(){
  $('#myBtn').show();

    $('#myBtn').off('click').on('click', $.proxy(function(e) {
        doSomething(this)
        // how you access the context of the button is using $(e.currentTarget)
    }, this));
});


window.doSomething = function(elem){
	console.log(elem)
}
#myBtn{
	display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="myTr" value="test">
<input type="button" id="myBtn" value="button">

3 Comments

There is a flaw in this code, you need to unbind the last click attached. Also why are you using bind and not on? It is deprecated.
@epascarello I'm not a jQuery expert, I just know how to use my resources and understand them, I just went bind at first as I didn't know on quite much. And I don't understand why he needs to unbind? he is only trying to pass the context and he can even also access the context within the button itself which I stated from my code. I don't want to argue, I am just trying to help. have a good one
click the button "myTr" twice in your example, than click the myBtn. You will see two console.log lines since multiple onlcick events will be bound to the button now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.