Reputation: 21
I'm using jQuery to generate a grid of divs that I will then style to become the board of a game. It works fine when I set the grid to 10 x 10, but when I increase the number of squares, even by one, the second column from the left either doesn't display at all (although the html is fine), or it extends from the bottom of the grid down instead of up.
I've tried messing with the stylesheet and pretty much every variable in the code to no avail. Any help would be appreciated.
$(document).ready(function() {
var row_count = 11;
var base = document.getElementById('base');
var square = '<div class="square"></div>';
var col_count = 11; // Sets the number of columns
while (col_count >= 0) { //Outer loops controls the columns.
row_count = 11; // sets the number of rows
while (row_count >= 0) {
$('<div class="square" id = "in_col' + '_' + col_count + '_' + row_count + '"></div>', {
"class": "square"
}).appendTo('#base');
row_count--;
}
col_count--;
}
// These two values, for posx and posy are the positioning
// coordinates for the squares of the grid
var posx = 10;
var posy = 10;
var col = 0; // Initiates the column counter for the below while loop
while (col <= 11) { // must match var col_count above
$.each($('div[id^="in_col_' + col + '"]'), function() {
$(this).css('top', posy);
$(this).css('left', posx);
posy += 41;
});
posy = 10;
posx += 41;
col++;
}
});
.square {
border: 1px solid black;
height: 40px;
width: 40px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='base'>
</div>
Fiddle of example
Upvotes: 2
Views: 111
Reputation: 21
IrkenInvader, thanks, I went with your solution, much cleaner than what I had originally and obviates the need for the bit of code (the regex in the jQuery selector) that was causing the problem.
$(document).ready(function(){
var col_count = 11;// Sets the number of columns
var row_count = 11; //sets the number of rows
var base = $('#base');
for(var i = 0; i < col_count; i++) {
for (var j = 0; j < row_count; j++) {
var square = '<div class="square" id = "in_col' + '_' + j + '_' + i +'"></div>';
var tile = $(square);
if (j === 0) tile.addClass('newRow');
base.append(tile);
}
}
});
Upvotes: 0
Reputation: 111
insted for running while loop backward run it forward, it will fix your problem
var row_count = 0;
var col_count = 0; // Sets the number of columns
while (col_count <= 10){ //Outer loops controls the columns.
row_count = 0; // sets the number of rows
while (row_count <= 10) { // Inner loop controls the cells in each column.
$('<div class="square" id = "in_col' + '_' + col_count + '_' + row_count +'"></div>', {"class":"square"}).appendTo('#base');
row_count++;
}
col_count++;
}
Upvotes: 0
Reputation: 4050
I refactored the code a bit, using for loops instead so we don't have to keep track of iteration variables. I also used float: left;
on the tiles and clear: both;
whenever we want to wrap down to a new line.
Javascript
$(document).ready(function() {
var col_count = 11; //Sets the number of columns
var row_count = 11; //sets the number of rows
var base = $('#base');
var square = '<div class="square"></div>';
for(var i = 0; i < col_count; i++){
for(var j = 0; j < row_count; j++){
var tile = $(square);
if(j === 0) tile.addClass('newRow');
base.append(tile);
}
}
});
CSS
.square {
border: 1px solid black;
height: 40px;
width: 40px;
float: left;
margin-top: -1px;
margin-left: -1px;
}
.newRow {
clear: both;
}
fiddle: https://jsfiddle.net/e0g6y9th/
Upvotes: 2
Reputation: 5007
Yours is more a mathematical problem. My version is much easier to understand, here is a fiddle.
go row by row and column by column in each row. so var i
is each row and var j
is each column in the row (starting every time by 1
and count up till reach var col_count
.
$(document).ready(function() {
var row_count = 11;
var col_count = 11;
var size = 41;
var base = document.getElementById('base');
for (var i=1; i<=row_count; i++) {
for (var j=1; j<=col_count; j++) {
$('<div class="square" id = "in_col' + '_' + j + '_' + i + '"></div>')
.addClass('square')
.css({
'left': j*size,
'top': i*size
})
.appendTo('#base');
}
}
});
to select each elements in column 1 use div[id^="in_col_1_"]
. I would recommend you to work with data attributes by changing the code to:
$(document).ready(function() {
var row_count = 11;
var col_count = 11;
var size = 41;
var base = document.getElementById('base');
for (var i=1; i<=row_count; i++) {
for (var j=1; j<=col_count; j++) {
$('<div class="square" id = "in_col' + '_' + j + '_' + i + '"></div>')
.addClass('square')
.attr('data-col', j)
.attr('data-row', i)
.css({
'left': j*size,
'top': i*size
})
.appendTo('#base');
}
}
});
so you can easily select elements in row 1 by div[data-row="1"]
and column 1 by div[data-col="1"]
. Have a look at this fiddle.
Upvotes: 0
Reputation: 10658
Here's my take
$(document).ready(function() {
var row_count = 11;
var col_count = 11;
var x = 0;
var y = 0;
var offX = 41;
var offY = 41;
for(var i = 0; i < col_count; i++){
$('#base').append('<div id="col_'+i+'" class="col" style="left:'+x+'px"><div>');
x += offX;
y = 0;
for(var j = 0; j < row_count; j++){
$('#col_'+i).append('<div class="square" id="row_'+j+'" style="top:'+y+'px"></div>');
y += offY;
}
}
});
.col{
position: absolute;
}
.square {
border: 1px solid black;
height: 40px;
width: 40px;
position: absolute;
}
Upvotes: 0
Reputation: 4412
The selector in your $.each loop is matching columns multiple times. A simple solution will be to zero-pad the numbers in your ids:
function pad(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}
Then change
$('<div class="square" id = "in_col' + '_' + col_count + '_' + row_count + '"></div>', {
"class": "square"
}).appendTo('#base');
To
$('<div class="square" id = "in_col' + '_' + pad(col_count,3) + '_' + pad(row_count,3) + '"></div>', {
"class": "square"
}).appendTo('#base');
And
$.each($('div[id^="in_col_' + col + '"]'), function() {
to
$.each($('div[id^="in_col_' + pad(col,3) + '"]'), function() {
Here's a working fiddle: https://jsfiddle.net/xc9gyv8p/4/
Upvotes: 0
Reputation: 1183
Problem is in $.each($('div[id^="in_col_' + col + '"]'), function() {
col_10 is called 2 times. Change it to $.each($('div[id^="in_col_' + col + '_"]'), function() {
, a more restrictive regex
$(document).ready(function() {
var row_count = 11;
var base = document.getElementById('base');
var square = '<div class="square"></div>';
var col_count = 11; // Sets the number of columns
while (col_count >= 0) { //Outer loops controls the columns.
row_count = 11; // sets the number of rows
while (row_count >= 0) {
$('<div class="square" id = "in_col' + '_' + col_count + '_' + row_count + '"></div>', {
"class": "square"
}).appendTo('#base');
row_count--;
}
col_count--;
}
// These two values, for posx and posy are the positioning
// coordinates for the squares of the grid
var posx = 10;
var posy = 10;
var col = 0; // Initiates the column counter for the below while loop
while (col <= 11) { // must match var col_count above
$.each($('div[id^="in_col_' + col + '_"]'), function() {
$(this).css('top', posy);
$(this).css('left', posx);
posy += 41;
});
posy = 10;
posx += 41;
col++;
}
});
.square {
border: 1px solid black;
height: 40px;
width: 40px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='base'>
</div>
Upvotes: 1