1

I've got a jQuery fucntion that performs a simple Ajax GET in ASP.Net and with the data (Json array) it gets back, populates a web page.

I'm attempting to bind a click event to each div created with the lopp below, but when this is run, all the click events happen on page load simultaneously!

Any ideas?

function grabList() {
    $('#temp').empty();

    $.ajax({
        url: '/Home/GoModel',
        method: 'GET',
        success: function (data) {             
            for (var i = 0; i < data.length; i++) {
                $('#temp').append('<div class="host col-sm-3"> id=' + data[i].name + '>' + data[i].name + '</div>');

                if (data[i].hostConnected === true) {
                    $('#temp').append('<div class="host connected col-sm-3" id=' + data[i].name + '>' + data[i].name + '</div>');
                    continue;
                }

                $('#' + data[i].name).on('click', connect(data[i].name)); // Problem occurs
            }
            $('#container').html($('#temp').html());
        }
    });
}
ma11achy
  • 133
  • 2
  • 14
  • Could you elaborate on what is happening exactly? What do you mean by "all click event happen on page load simultaneously"? Also, what is the code for the `connect` function? – Can Ibanoglu Aug 04 '16 at 16:18
  • Possible duplicate of [Javascript infamous Loop issue?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue) – Heretic Monkey Aug 04 '16 at 16:57

3 Answers3

2

You may try:

function grabList() {
  $('#temp').empty();

  $.ajax({
    url: 'https://api.github.com/repositories?since=700',
    method: 'GET',
    success: function (data) {
      for (var i = 0; i < data.length; i++) {
        $('#temp').append('<div class="host col-sm-3" id=' + data[i].name + '>' + data[i].name + '</div>');

        if (data[i].hostConnected === true) {
          $('#temp').append('<div class="host connected col-sm-3" id=' + data[i].name + '>' + data[i].name + '</div>');
          continue;
        }

        (function (ele) {
          $('#' + ele).on('click', function (e) {
            alert(ele);
          });
        })(data[i].name);
      }
      $('#container').html($('#temp').html());
    }
  });
}

$(function () {
  grabList();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>


<div id="temp"></div>
<div id="container"></div>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
0

It is not firing the event, you are making a call in the binding :

$('#' + data[i].name).on('click', connect(data[i].name)); 

You need to do it like this :

$('#' + data[i].name).data({name : data[i].name});
    $('#' + data[i].name).on('click', function(e){connect($(e.target).data().name);}); 
Rich Linnell
  • 973
  • 5
  • 14
  • This won't work. This is common "Closure-In-Loop" mistake. `i` will change by the moment of click event. – Alex Kudryashev Aug 04 '16 at 16:44
  • Ah yes, well spotted Alex. Apologies, I was focusing on the main issue. To get around this write the value of data[i].name to the data attribute on the created element and lift it off in the function. I've amended the answer to reflect this – Rich Linnell Aug 04 '16 at 17:52
0

You are, in fact, calling the connect() function when binding to the click event instead of when the event is fired (later).

Since you want to pass data into the event handler, you'll need to use additional parameters of the .on() call. Try something like this instead.

$('#' + data[i].name).on('click', null, data[i].name, function (e) {
    connect(e.data);
});
ventaur
  • 1,821
  • 11
  • 24