2

I am trying to append a number of Div's to a div with an id "list", and each div has an event so i make an array for each div to be appended. here is my code.

var count = Object.keys(data.results).length;
        var el = [];
          for(var i=1; i<=count; i++){
            el[i] = $('<div id="'+i+'">data.results[i].name</div>');
            $("#list").append(el[i]);
            el[i].click(function(){
              alert(data.results[i].name);
              $('#searchbox').modal('toggle');
            });
          }

the data in div's was successfully appended. but as a try to alert the data in the event i bind to each div, it doesn't alert the data in the div.

what I am trying to do is append names with a div within the div with id "list" and if i click on a name, it should alert the name itself.

Francis Rubia
  • 439
  • 2
  • 6
  • 14
  • another thing i observed is that if i alert the variable 'i' which is declared in the for loop, is that example the results appended was 5 names. so if i click on the first name it should alert 1 instead it alerts 5. i'm so confused. – Francis Rubia Apr 04 '17 at 08:51
  • Related: [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – The `click` `function` will evaluate `i` for the value it has at the time that the event occurred, which is well after the `for` loop has finished incrementing `i` until it equals `count`. (An alternative would be to use [`let i`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) in place of `var i`, though note its browser support.) – Jonathan Lonowski Apr 04 '17 at 08:52
  • @JonathanLonowski ok. i see thanks for that. – Francis Rubia Apr 04 '17 at 08:56

2 Answers2

3

You can simplify the logic here by using a delegated event handler on all the appended div elements, then using the text() method to retrieve the required value. Try this:

var data = {
  results: {
    foo: { name: 'foo_name' },
    bar: { name: 'bar_name' }
  }
}

var $list = $("#list").on('click', 'div', function() {
  console.log($(this).text());
  //$('#searchbox').modal('toggle');
});

Object.keys(data.results).forEach(function(key, i) {
  $list.append('<div id="' + i + '">' + data.results[key].name + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list"></div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
1

The problem is that by the time an element is clicked i is already set to the maximum value i = count. To fix that you'll have to create a closure. Try this:

var count = Object.keys(data.results).length;
var el = [];
function closure(index){
  el[index].click(function(){
    alert(data.results[index].name);
    $('#searchbox').modal('toggle');
  });
}
for(var i=1; i<=count; i++){
  el[i] = $('<div id="'+i+'">data.results[i].name</div>');
  $("#list").append(el[i]);
  closure(i);
}
Titus
  • 22,031
  • 1
  • 23
  • 33