cisco cisco - 2 months ago 11
Javascript Question

closure loop in ajax callback

i have a data which were parsed from json, i display the data in a box like facebook's friends suggestion box. i want when the user click on any of the suggested users the request to be added to DB via ajax and its corresponding button disappears,everything is working just fine except the last thing(button disappears) instead the very first button in the list gets disappear, while im searching for a solution to my problem i came across something called closure but i reaaly couldn't know how to implement it in my code, another problem appeared when i tried to declare the listener anonymous function inside the loop was the data get inserted in the DB multiple times
(because its inside a loop), i know it might seems duplicated question but i just need someone pointing me the right place to declare my inner function,

my code looks like this

$(document).ready(function() {
var suggest = new XMLHttpRequest();
suggest.onreadystatechange = function() {
if (suggest.readyState === 4 && suggest.status === 200) {
var susers = JSON.parse(suggest.responseText);

for (var i = 0; i < susers.length; i += 1) {
var sphoto = '<div class="col-md-4 text-left "> <div id="fimage">';
sphoto += '<img width="50" height="50" src="user/';
sphoto += susers[i].activation + '/' + susers[i].pic + '"> </div> </div>';
var sname = '<div id="fname">' + susers[i].name + '</div>';

// here is the form im targetting to pull informtion from
var hidden = '<form id="fform"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';

var fbutton = '<button id="addfriend"class="btn btn-info btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button></form';


var display = document.getElementById('fsuggest');
display.innerHTML += '<div class="scroller"><div id="fspace" > <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + sphoto + sname + hidden + fbutton +'</div></div>'

$('#addfriend').live('click', function(arg) {
return function() {
arg.preventDefault();
var data = $('#fform').serialize();
$.ajax({
data: data,
type: "post",
url: "addnew.php",
success: function(data) {
//make the text area empty
$('#addfriend').css("display", "none");
console.log(data);
}

}); // end of $.ajax

}(i); // end of inner function

}); // end of click listner



} //end of for loop

}
};

suggest.open('GET', 'box.php');
suggest.send();
}); // end of JQUERY ready

Answer

I am not sure why exactly you need closure here. The problem seems to be with the multiple form & button with same id.

All these buttons have same id so the forms. So

$('#addfriend').live('click', function(arg) {..}) has no reference to the particular button 

Hope this change will help

Con-cat the value of iwith the id of the form & add an attribute data-id=i the button.

Beside instead of id add class addfriend to the button. So when this button will be clicked take the data-id value. Use this value to get the relevant form with id , & serialize that

var hidden = '<form id="fform_' + i + '"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';


var fbutton = '<button data-id="' + i + '" id=""class=" addfriend btn btn-info  btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button>';

Make below change to the click function.

Also reason of adding the event handler inside loop is not clear.

 $('.addfriend').live('click', function(arg) {
           arg.preventDefault();
           var getDataId = $(this).attr('data-id')  // get the data-id
            var data = $('#fform_'+getDataId).serialize(); // get relevant form
            $.ajax({
              // rest of code
           }); // end of $.ajax
           })

Try to use jquery version above 1.9 to use the on method for event delegation

Comments