how to 'bake' parameters into click() call jquery?

Go To StackoverFlow.com

1

I've got an ajax call that collects XML, and based on that data creates a number of divs on which I attach click() jquery listeners. When clicked, I want those divs to call a function and to pass a parameter into that function. However, by the time the click is called the value of the parameter has changed. Here's an example from a jsfiddle I built to demonstrate the problem:

    $(document).ready(function() {

    function x() {

      $.ajax({
        type: "POST",
        url: "/echo/xml/",
        dataType: "xml",
        data: {
            xml: "<the>xml</the>"
        },
        success: function(xml) { 
          console.log('success');                

          $('#test').show(); 

          var text = "CORRECT";      

          $('#test').click(function() {

            insertText(text);
            console.log(text);
          });

          text = "WRONG";

        }        
      });
    }

    x();

  });

  function insertText(t) {

      $('#test').html(t);
  }

I want the text to show up as CORRECT, not WRONG.

​I know this is a bit of a convoluted example but I'm trying to simulate my actual code as much as possible in terms of scope and what is going on. By the time the click() function gets called based on a click, the value of text has changed. Is there some way to 'bake' the value of text into the click() call at the time I create it? I'll be creating a number of these through a for loop as it runs through the XML and don't want to hang on to all that data into variables for use later.

2012-04-03 21:15
by mix
The click handler will always show the text variable with a value as wrong, this is because you can't possibly click it fast enough before you have changed the value of text. I don't understand why you need to do it this way - Neil 2012-04-03 21:25
i should have added more of the structure for my example. this click binding code exists within a for() loop that runs through all named elements of an XML document, binding clicks with associated parms based on IDs. IOW, it creates a number of divs, each with click() functions that need to know a parm that was gathered at the time the div was created/set during the for loop - mix 2012-04-03 21:29


1

The easiest way is probably to create a function that attaches the handler. In this way, the parameter within the function is unchanged.

      var text = "CORRECT";      

      bindClick("test", text);


      // ...

      function bindClick(id, text){

          $('#' + id).click(function() {
            insertText(text);
            console.log(text);
          });
      }

http://jsfiddle.net/snTEf/2/

2012-04-03 21:23
by James Montagne
i see. makes sense and totally works - mix 2012-04-03 21:29


1

Like this -- you bind it to a local variable in a closure form.

(function(text){
     $('#test').click(function() {
            insertText(text);
            console.log(text);
      });
})(text);
2012-04-03 21:28
by Soren


1

The click function isn't called until after the text = "WRONG" assignment gets called, so of course the function uses the "incorrect" value of text. If you want to, as you say, bake the value of text into your function at definition time, you can use an immediately-invoked anonymous function like so:

(function(bakedText) {
  $('#test').click( function() {
    insertText(bakedText);
    console.log(bakedText);
  }
})(text);

See demonstration here: http://jsfiddle.net/H4DpV/

2012-04-03 21:29
by Ethan Brown