-1

I've been sticking around with a problem for a while and can't find any solutions. Even though I've read this question and answers on stackoverflow, I can't figure out whats wrong. Probably due to a lack of good english. So German answers are welcome.

However, I'm trying to pass a variable into another function outside the for-loop. Here's my code:

"use strict";
// gobal vars
var sort = new Array();

$(document).ready(function(){

// Sortable.js
// Copyright 2013-2015 Lebedev Konstantin <ibnRubaXa@gmail.com>
// http://rubaxa.github.io/Sortable/

    var min = 2,
        max = 5,
        elems = new Array();
    elems[0] = document.getElementById("left");
    elems[1] = document.getElementById("center");
    elems[2] = document.getElementById("right");

    for(var i=0, len=elems.length; i<len; i++) {
        var amnt = elems[i].getElementsByTagName("div").length,
            group = "gewicht";
        if (amnt <= min) {
            group = {name: "gewicht", pull: false, put: true};
        } else if (amnt >= max) {
            group = {name: "gewicht", pull: true, put: false};
        }
        sort[i] = Sortable.create(elems[i], {
            group: group,
            animation: 150,
            ghostClass:"ghost",
            draggable: ".draggable",
            onSort: function(evt) {sortEnd(evt, i, min, max)}
        })
    }
});

function sortEnd(evt, j, min, max) {
    var targ = evt.target,
        amnt = targ.getElementsByTagName("div").length;
    console.log(j);
    amnt = targ.getElementsByTagName("div").length;
    if (amnt <= min) {
        sort[j].option("group", {name: "gewicht", pull: false, put: true});
    } else if (amnt > max) {
        sort[j].option("group", {name: "gewicht", pull: true, put: false});
    } else {
        sort[j].option("group", {name: "gewicht", pull: true, put: true});
    }
}

The problem is at onSort: function(evt) {sortEnd(evt, i, min, max)}, where the variable i inside the for loop will be 0, 1 and 2. But outside the loop, the console.log() in the function sortEnd() it will return 3.

An explanation which I can understand would be good, a solution for my problem even better, both would be best.

Thanks

Community
  • 1
  • 1
Norman
  • 785
  • 7
  • 27
  • 1
    `onSort: function(evt) {sortEnd(evt, i, min, max)}` is going to use the value that `i` is when this function runs, which is probably after the `for` loop has finished looping. So, `i` will be equal to the final value it was assigned while looping, `3`. – forgivenson Mar 30 '15 at 14:44
  • Thanks for the quick answer, but this just explains whats happening, but not how to solve this problem. – Norman Mar 30 '15 at 14:49

2 Answers2

1

Per the linked question, you need to wrap your operation in a function:

(function(group, i) {
  sort.push(Sortable.create(elems[i], {
    group: group,
    animation: 150,
    ghostClass:"ghost",
    draggable: ".draggable",
    onSort: function(evt) {sortEnd(evt, i, min, max)}
  }))
}(group, i));

Otherwise every instance of group and i will refer to the same value.

Also, when working with arrays, use push rather than setting IDs directly.

Evan Davis
  • 35,493
  • 6
  • 50
  • 57
  • Thanks, this worked perfectly! and another thanks for the .push(), almost forgot about that. – Norman Mar 30 '15 at 14:52
0

The problem is that your i variable is being captured and then the value of it is changing. The best solution to this is an IIFE (immediately invoked function expression):

for (var i = 0, len = elems.length; i < len; i++) {
  ..
  (function(val) {
    sort[val] = Sortable.create(elems[val], {
        group: group,
        animation: 150,
        ghostClass:"ghost",
        draggable: ".draggable",
        onSort: function(evt) {sortEnd(evt, val, min, max)}
    });
  })(i);
}
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91