Reputation: 190
I am building a web app which contains a DOM table. This is my code that should create a table from an array:
function create_table() {
var tablediv=document.getElementById('icon-table');
var table = document.createElement("table");
var grid = [[15][15]];
var template = "pixel-{1}-{2}";
table.className = "icon-table";
tablediv.appendChild(table);
for (var i = 0; i < 16; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
td.className = "icon-pixel";
td.id="pixel-"+ i + "-" + j;
td.style.backgroundColor = "rgb(255,255,255)"; // no dash - css attribute name becomes camelCase
grid[i][j] = td;
td.addEventListener("click", setpixel)
td.addEventListener("mousedown", pinselpixel)
tr.appendChild(td);
}
}
}
The assignment grid[i][j] = td; fails during the first loop iteration. On the console in my browser the output says:
TypeError: undefined is not an object (evaluating 'grid[i][j] = td')
what am I missing?
Upvotes: 1
Views: 545
Reputation: 2320
Can change to this and try it?
var grid = [[15][15]];
to
var grid = [new Array(15), new Array(15)];
Upvotes: 1
Reputation: 34556
There's a couple of problems here. First, you seem to be under the impression that
[[15],[15]]
will create an an array with two sub-arrays, each with 15 keys.
Instead, what that actually gives you is an array with two sub-arrays each containing one key each, with the value 15.
You probably meant this:
[new Array(15), new Array(15)]
Passing an integer to the array constructor creates the slots; passing it to an array literal simply adds that value to the array.
Even then, this approach isn't ideal. Yes, you're containing 15 (actually you presumably meant 16) slots, but they're just undefined
slots right now, so this line will fail, since you can't treat undefined
as an array:
grid[i][j] = td; //grid[i] == undefined, not an array
Better this (truncated for brevity):
for (var i = 0; i < 16; i++) {
grid[i] = []; //<-- create the row array in the loop
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
grid[i][j] = td; //<-- now we can append the column cell
tr.appendChild(td);
}
}
Upvotes: 3
Reputation: 26527
Your grid
initialization is wrong. As mentioned by some comments:
var grid = [[15][15]];
is equivalent to:
const arr = [15]; // array with one element, 15
var grid = arr[15]; // 16th element, which doesn't exist
You probably instead want:
var grid = new Array(15).fill(new Array(15));
Which will give you a two-dimensional array that is 15 "wide" and 15 "tall".
That said, you really don't need to prefill your grid unless it is a requirement for some other reason (like you are printing out a chessboard or something that always has a fixed size).
Upvotes: 1
Reputation: 56297
The method of intializing the two dimensional array is wrong.
Please use the below method to initialize.
var grid = new Array(15);
for (var i = 0; i < 16; i++) {
grid[i] = new Array(15);
}
First we create the rows of the array (15 rows
), then using a for loop we initialize 15 columns
for each row. Then the code works fine!
function create_table() {
var tablediv=document.getElementById('icon-table');
var table = document.createElement("table");
var grid = new Array(15);
for (var i = 0; i < 16; i++) {
grid[i] = new Array(15);
}
var template = "pixel-{1}-{2}";
table.className = "icon-table";
tablediv.appendChild(table);
for (var i = 0; i < 16; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
td.className = "icon-pixel";
td.id="pixel-"+ i + "-" + j;
td.style.backgroundColor = "rgb(255,255,255)"; // no dash - css attribute name becomes camelCase
grid[i][j] = td;
td.addEventListener("click", function(){console.log("clicked");})
td.addEventListener("mousedown", function(){console.log("mousedown");})
tr.appendChild(td);
}
}
}
create_table();
<div id="icon-table"></div>
Upvotes: 1
Reputation: 5629
you are trying to loop over an array of array which has 2 elements inside. Each element is (like i said) an array, with a single entry - in your case 15
.
Afterwards you are trying to iterate from 0 up to 15.
So your iterations should at first loop over grid
array and afterwards over grid
's elements up to their length.
but in my opinion it is not necessary to loop over an array here. just do the following:
var myGrid = []
for (var i = 0; i < 16; i++) {
for var k = 0; k < 16; k++) {
//do your stuff
myGrid[i][k] = td
}
}
this should work
Upvotes: 3