0

I've had a look around SO for a clue regarding the issue i'm currently facing, but I just don't seem to get the issue. Essentially the variables that are defined within the $(allSelects).change(function(){... are not being given the value of a variable defined outside of that function.

Originally I had the whole select path in there, but attempted to reduce the repetition in the script. Does anyone know what I'm doing wrong, and why these values are undefined even though they are defined? I thought perhaps it was a matter of scope, but the variables within the aforementioned function should be able to see the ones outside of that function.

Any help would be appreciated. Here is my code...

$(window).load(function(){

var productFamily = ["Beaches","Leios","Lull"];
var productType = ["Shelter","Restroom"];
var sizeRange = ["4x4","6x4","8x4","8x6"];

for ( let p in productFamily) {
  for ( let t in productType ) {
    for ( let i in sizeRange ) {

    var selectSize = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' Size]"]';
    var selectFrame = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Frame]"]';
    var selectFasteners = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Fasteners]"]';
    var selectRoof = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Roof]"]';
    var selectInfill = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Infill]"]';
    var selectColumns = 'select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Column]"]';
    var allSelects =  selectSize + ',' + selectFrame + ',' + selectFasteners + ',' + selectRoof + ',' + selectInfill + ',' + selectColumns;

    console.log(allSelects);

    $(allSelects).change(function(){

        var mySizeSelection = $(selectSize).val();
        var myFrameSelection = $(selectFrame).val();
        var myFastenersSelection = $(selectFasteners).val();
        var myColumnSelection = $(selectColumns).val();
        var myInfillSelection = $(selectInfill).val();
        var myRoofSelection = $(selectRoof).val();

        if (mySizeSelection == null) {
          console.log("This variable is null.");
        }

        if ( mySizeSelection == "4x4" ) {
          mySizeSelection = "44";
        } else if ( mySizeSelection == "6x4" ) {
          mySizeSelection = "64";
        } else if ( mySizeSelection == "8x4" ) {
          mySizeSelection = "84";
        } else if ( mySizeSelection == "8x6" ) {
          mySizeSelection = "86";
        } else {
          mySizeSelection = "Error";
        }

        if ( myFrameSelection == "Galvanised" ) {
          myFrameSelection = "G";
        } else if ( myFrameSelection == "Painted" ) {
          myFrameSelection = "P";
        } else {
          myFrameSelection = "Error";
        }

        if ( myColumnSelection == "Galvanised" ) {
          myColumnSelection = "G";
        } else {
          myColumnSelection = "P";
        }

        if ( myRoofSelection == "Colorbond" ) {
          myRoofSelection = "C";
        } else if ( myRoofSelection == "Polycarbonite"  ) {
          myRoofSelection = "P";
        } else {
          myRoofSelection = "N";
        }

        if ( myInfillSelection == "Yes" ) {
          myInfillSelection = "Y";
        } else {
          myInfillSelection = "N";
        }

        if ( myFastenersSelection == "Galvanised" ) {
          myFastenersSelection = "G";
        } else if ( myFastenersSelection == "Stainless Steel" ) {
          myFastenersSelection = "G";
        } else {
          myFastenersSelection = "Error";
        }

        if ( (mySizeSelection) || (myFrameSelection) || (myFastenersSelection) ) {
            var url = "//my.testwebsite.com/"+ productFamily[p] + "_" + productType[t] + "/" + productFamily[p].toUpperCase() + "_" + mySizeSelection + myFrameSelection + "C" + myFastenersSelection + ".jpg";
            $('.product-main-image img').attr("src",url);
            console.log(url);
        } else {
            $('.product-main-image img').attr("src","//another.website.com/logo.png");
        }

    });
  }
}
}

});

As mentioned in my comments below, i'm posting the original script before my attempt at making it more concise, as you can see there is some repetition, and a gigantic amount of stuff in the change handler.

$(window).load(function(){

  var productFamily = ["Beaches","Leios","Lull"];
  var productType = ["Shelter","Restroom"];
  var sizeRange = ["4x4","6x4","8x4","8x6"];

  for ( let p in productFamily ) {
    for ( let t in productType ) {
      for ( let i in sizeRange ) {

        $(' select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' Size]"],select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Frame]"], select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Fasteners]"],select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Roof]"], select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Infill]"], select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Column]"]').change(function(){

            var mySizeSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' Size]"]').val();
            var myFrameSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Frame]"]').val();
            var myFastenersSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Fasteners]"]').val();
            var myColumnSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Roof]"]').val();
            var myInfillSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Infill]"]').val();
            var myRoofSelection = $('select[name="properties[' + productFamily[p] + ' ' + productType[t] + ' ' + sizeRange[i] + ' Column]"]').val();

            if (mySizeSelection == null) {
              console.log("This variable is null.");
            }

            if ( mySizeSelection == "4x4" ) {
              mySizeSelection = "44";
            } else if ( mySizeSelection == "6x4" ) {
              mySizeSelection = "64";
            } else if ( mySizeSelection == "8x4" ) {
              mySizeSelection = "84";
            } else {
              mySizeSelection = "86";
            }

            if ( myFrameSelection == "Galvanised" ) {
              myFrameSelection = "G";
            } else {
              myFrameSelection = "P";
            }

            if ( myColumnSelection == "Galvanised" ) {
              myColumnSelection = "G";
            } else {
              myColumnSelection = "P";
            }

            if ( myRoofSelection == "Colorbond" ) {
              myRoofSelection = "C";
            } else if ( myRoofSelection == "Polycarbonite"  ) {
              myRoofSelection = "P";
            } else {
              myRoofSelection = "N";
            }

            if ( myInfillSelection == "Yes" ) {
              myInfillSelection = "Y";
            } else {
              myInfillSelection = "N";
            }

            if ( myFastenersSelection == "Galvanised" ) {
              myFastenersSelection = "G";
            } else {
              myFastenersSelection = "G";
            }

            if ( (mySizeSelection) || (myFrameSelection) || (myFastenersSelection) ) {
            var url = "//my.testwebsite.com/"+ productFamily[p] + "_" + productType[t] + "/" + productFamily[p].toUpperCase() + "_" + mySizeSelection + myFrameSelection + "C" + myFastenersSelection + ".jpg";
                $('.product-main-image img').attr("src",url);
                console.log(url);
            } else {
                $('.product-main-image img').attr("src","//another.website.com/logo.png");
            }


        });
      }
    }
  }

});
Marko
  • 102
  • 1
  • 10
  • 1
    Have you tried using `let` instead of `var`? If you use `var` all of the change handlers share the same variables. – nnnnnn Aug 08 '16 at 08:28
  • Remember `let` defined variables must be initialised before use, unlike `var`, they don't get hoisted and they are bound to the block scope, not function scope. – evolutionxbox Aug 08 '16 at 08:29
  • 1
    @jcubic - I don't think this is a duplicate, as the variables are not affected by a lack of a closure. - I think this should be reopened, unless someone can explain why it's a duplicate. – evolutionxbox Aug 08 '16 at 08:34
  • You are not directly referencing `p`, `t` or `i` in the `onchange` handler function so @jcubic suggestion is wrong as the marked duplicate is about that issue, although your innermost loop runs 24 times hence `allSelects` is defined 24 times and you assign 24 change handlers to `$(allSelects)` all of which executes on every change. I'd start looking in that direction. – marekful Aug 08 '16 at 08:57
  • @nnnnnn tried using var, no dice i'm afraid. @marekful - I've now tried moving the change handler to surround the loops (just made it listen for changes to `html`), and I still get the same issue. I think you're on the right track though, it was working earlier when I wasn't using variables and was explicitly defining `p`,`t` and `i` - however I made this attempt because it was quite verbose before. I'll go and post the original to see if anyone has any suggestions on how to make it less long-winded. – Marko Aug 08 '16 at 23:56

0 Answers0