1
var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){
            $.ajax({
                type: 'POST',
                url: 'delete.php',
                data: {filek : smth[i]},
                success: function(html){
                    console.log(html);
                }
            });
    });
};

How send "smth[i]" by data in ajax? When I make var before ajax its alwayes be the last one and all buttons send last element of array.

KanekiSenpai
  • 122
  • 10
  • This isn't really efficient, you have put your ajax in a loop – IROEGBU Oct 28 '17 at 00:04
  • 1
    @IROEGBU No he hasn't. The loop is just binding click handlers. – Barmar Oct 28 '17 at 00:04
  • numbered ids are always a sign for a design error. would be so much easier to give all these elements a css class. so you don't need the for loop anymore. – Joshua K Oct 28 '17 at 00:09
  • @JoshuaK That would then require additional mechanism to relate them to the `smth` array, like adding a `data-smthindex="1"` attribute. – Barmar Oct 28 '17 at 00:24

4 Answers4

0

The handler can get the target element's ID and extract i from that:

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){
        var i = parseInt(this.id.substr(2), 10);
        $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[i]},
            success: function(html){
                console.log(html);
            }
        });
    });
};

Other more general solutions to the problem of iteration variables and closures can be found here: JavaScript closure inside loops – simple practical example

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • why extracting `i`? just replace `var i` with `let i` and it works without getting `i` from the `id`. But the whole thing with the loop is a bad idea in my opnion. jquery iterates over it by itself. No need for that. – Joshua K Oct 28 '17 at 00:18
0

Don't use a for loop for that and don't use numbered ids. But if you HAVE to use numbered ids and cannot add a css class: just check the beginning and the end so you don't need the loop:

var smth = ["1","2","3"];
$("[id^=id][id$=_del]").click(function(){
    let i = parseInt(this.id.substr(2), 10);
    $.ajax({
        type: 'POST',
        url: 'delete.php',
        data: {filek : smth[i]},
        success: function(html){
            console.log(html);
        }
    });
};
Joshua K
  • 2,407
  • 1
  • 10
  • 13
0

To avoid messing with indexed loops you could try the regex approach, something like this:

$('div')
  .filter(function() {
    return this.id.match(/^id\d+_del$/);
  })
  .click(function() {
    let id = this.id.match(/id(\d+)_del/)[1];

    $.ajax({
      type: 'POST',
      url: 'delete.php',
      data: { filek: smth[id] },
      success: function(html) {
        console.log(html);
      },
    });
  });

JSFiddle (check the network tab for the XHRs)

Basically it takes all divs with ids starting with id, having some number in the middle and ending with _del, then binds an ajax call to each one using the number captured from the id. IMO this is a lot cleaner, although you still have to make sure that smth has all the items you need.

That said, like others mentioned, I'd suggest using classes and data attributes in the divs, that can leverage safer and smarter solutions without tricks like this.

EDIT:

Class/data approach:

$('.del').click(function() {
  let id = $(this).data('filek-id');

  console.log(`Id: ${id}`);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="del" data-filek-id="0">Foo click me</div>
<div class="del" data-filek-id="1">Bar click me</div>
<div class="del" data-filek-id="2">Baz click me</div>
Pedro Fialho
  • 444
  • 8
  • 18
0

The question in OP was discussed on SO many and many times. The name of the problem is Asynchronous function execution in the loop.

First look what is wrong with OP:

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){// i comes from the loop and is OK
        $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[i]},//the code runs *after* the loop is completed and **i** is 3 (in this case)
            success: function(html){
                console.log(html);
            }
        });
    });
};

How to fix it?
If ES6 is available then there is no problem. Read documentation

for(let i=0;i<smth.length;i++){// i is scoped to the loop
//  ^^^
// OP code
}

Else a closure is the solution

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
   (function(j){ // it is possible to use **i** but it will be different **i**
     $("#id"+j+"_del").click(function(){// 
          $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[j]},// j keeps the value
            success: function(html){
                console.log(html);
            }
        });

    });})(i);
};
Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36