Josh
Josh

Reputation: 71

JS Referencing array element values by variables?

My project includes an array filled with objects. Each object has a property called "on" which is either true or false. Previously my code was the following (and it worked.)

HTML

<li><div class='square' id='square_1_1'></div></li>
<li><div class='square' id='square_1_2'></div></li>
<li><div class='square' id='square_1_3'></div></li>

JS

//creates the Square object
function Square(x,y, sound, on) {
    this.x = x,
    this.y = y,
    this.sound = sound, 
    this.on = false
};

//made some squares
var square_1_1 = new Square(1, 1, sound36);
var square_1_2 = new Square(1, 2, sound35);
var square_1_3 = new Square(1, 3, sound34);
...


$('.square').click(function() {
    $(this).toggleClass('on'); // Just toggles the css
    var currentId = $(this).attr("id");
    window[currentId].on = !(window[currentId].on)

});

The above code did the following: When a div was clicked the ID was stored into a variable. A JS object with the same name of the variable was found and its 'on' property was then turned true or false.

I wanted to rewrite a few things so I cleared up the DOM. I also want to reuse this code so I can have multiple pages. Now my code looks like this:

HTML

<li><div class='square' id='page1Buttons[0]'></div></li>
<li><div class='square' id='page1Buttons[1]'></div></li>
<li><div class='square' id='page1Buttons[2]'></div></li>

JS

//SAME AS BEFORE
// creates the Button object
function Button(x,y, sound, on) {
    this.x = x,
    this.y = y,
    this.sound = sound, 
    this.on = false
};

//use a loop function to create the Square objects. Put all objects in an array
var page1Buttons = [];
var fillPage1Buttons = function (){
    //fill a column of buttons
        var rows = 1;
        for(rows; rows <= 36; rows += 1) {
        var i = 0;
        for(i; i <= 35; i ++) {
            page1Buttons[page1Buttons.length] = new Button(rows, i + 1, bellsArray[i]);
        }
        }
}();



// This is the part that is not working
var currentId;
var currentObject;
$('.square').click(function() {
    $(this).toggleClass('on');
    currentId = $(this).attr("id");
    window[currentId].on = !(window[currentId].on);
});

If I use the JS console and type:

page1Buttons[0].on = !page1Buttons[0].on;

I can change the property. The part I can't figure out is this:

window[currentId].on = !(window[currentId].on);

I've tried a few things, but I'm either getting a string or undefined.

Upvotes: 0

Views: 31

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074335

I would stop using globals entirely, and so stop using window entirely, as you've already taken the first step that way.

Instead, I'd store the index into the pageButtons array as a data attribute (although you could still use id for it if you like):

<li><div class='square' data-id='0'></div></li>
<li><div class='square' data-id='1'></div></li>
<li><div class='square' data-id='2'></div></li>

then:

$('.square').click(function() {
    $(this).toggleClass('on');
    currentId = $(this).attr("data-id");
    pageButtons[currentId].on = !pageButtons[currentId].on; // No need for the ()
});

Alternately, you could use jQuery's nifty data function to directly connect your Square instances to the elements. That would work best if you dynamically created the divs as well.

function Button(x,y, sound, on) {
    this.x = x,
    this.y = y,
    this.sound = sound, 
    this.on = false
}
var n, li, btn;
var list = $("#the-list");
var display = $("#display");
var pageButtons = [];
for (n = 0; n < 10; ++n) {
  li = $('<li><div class="square"></div></li>');
  btn = new Button(0, n, 'whatever', false);
  li.find('div').data('btn', btn);
  list.append(li);
  pageButtons.push(btn);
}
$(".square").on("click", function() {
  var $this = $(this);
  $this.toggleClass('on');
  $this.data('btn').on = $this.hasClass('on');
  // Show that the buttons are updated
  display.html(pageButtons.map(function(btn, i) {
    return "<div>#" + i + " is " + (btn.on ? "on" : "off") + "</div>";
  }).join(""));
});
.square {
  display: inline-block;
  width: 10px;
  height: 10px;
  background-color: #ddd;
}
.on {
  background-color: green;
}
#the-list {
  float: left;
  width: 30%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="the-list"></ul>
<div id="display"></div>

Upvotes: 1

Related Questions