views:

37

answers:

2

I'm new to JQuery and don't have a huge background in Javascript, either - so that could be contributing to my problems... I'm trying to dynamically generate a list of items and bind click events to each of the dynamically generated elements. I can create the list and successfully bind the click events, but then I ran into a stumbling block.

I need to be able to have each click event access specific data associated with the item that was clicked. My initial though was to just include the data in the dynamic function that I create when I bind the click event. The code below tries to do this, but whenever I click an element in the list, I only get the final value of my counter variable (2).

Clearly I'm misunderstanding the way my click function is created. I've read a whole bunch of items here at SO that might be related, but I haven't found the elegant/correct way to accomplish this yet.

My test page:

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>

    <script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>

    <script type="text/javascript">
function generateList() {
  var listElement = $('#unsortedList');
  var dataArr = new Array();
  dataArr["name1"] = "value1";
  dataArr["name2"] = "value2";

  // Clear any existing HTML
  listElement.html('');

  var i = 0;
  for(item in dataArr) {
    listElement.append('<li><div id="item' + i + '">Item ' + i + '</div></li>');

    $('#item' + i).click(function() {
      alert(i);
      $('#item' + i).html("You clicked item " + i);
    });

    i++;
  }
}

$(document).ready(function(e){
  generateList();
});

    </script>
  </head>
  <body>
    <h1>Test List</h1>
    <ul id="unsortedList">
    </ul>
  </body>
</html>

[EDIT] - My ultimate goal is to use the counter variable value to index into an external array of values. I know it seems a little disconnected in the example. When you click the item, I want to pull out an index into an array, run a function that will generate a value that I will use to populate another element in the same dynamic list item.

+3  A: 

This works :

 $('#item' + i).click((function(x) {
          return function(){
              $('#item' + x).html("You clicked item " + x);
          };
        })(i));

tested it here : http://jsfiddle.net/uLGxb/

NM
What you need is closure here . Let me know if this works as I didn't get a chance to test this .
NM
I see the idea here, but I tried it and it didn't appear to change anything. Both elements still receive '2' as the value of x.
Quintus
I think, in this case, "x" will be an event object (depending on the browser). If you were to remove the "x" parameter from the line "return function(x)", I think it would be perfect.
Ryan Kinal
Try now . It should work .
NM
This works! And as an added bonus, I even think I understand *why*. Thanks!
Quintus
A: 

NM - nice simple solution. of course, the inner section could equally be written as:

      return function(){
          $(this).html("You clicked item " + x);
      };

cheers...

jim

jim