Reset Button in Javascript Tic Tac Toe Game - javascript

I'm making a Javascript Tic Tac Toe Game, and I'm having trouble with the reset button. I believe that in my clickHandler function, I should be calling the blankPattern function. It's not working, though.
<!doctype html>
<html>
<head>
<title>Tic Tac Toe</title>
<style>
#stage {
position:relative;
}
.cell {
position:absolute;
border:3px solid black;
background-color:white;
font-size: 300px;
text-align: center;
color: red;
}
#reset {
font-family: "Lucida Console", Monaco, monospace;
color: white;
height: 100px;
width: 150px;
background-color:black;
top: 45%;
left: 50%;
position: absolute;
font-size: 30px;
}
</style>
</head>
<body>
<div id="stage"></div>
<button id = "reset">Reset</button>
<script>
var reset = document.querySelector("#reset");
reset.style.cursor = "pointer";
reset.addEventListener("click", clickHandler, false);
// GRAB A REFERENCE TO THE STAGE
var stage = document.querySelector("#stage");
// THE SIZE AND SPACE OF EACH CELL
var SIZE = 290;
var SPACE = 0;
// THE ARRAY DIMENSIONS - TRY CHANGING THESE TO GET LARGER OR SMALLER GRAPHS
var MAXROWS = 3;
var MAXCOLS = 3;
// THE 2D ARRAY THAT DEFINES THE PATTERN
var pattern = blankPattern();
// CREATE THE DIVS and POSITION THEM IN THE STAGE... BUT DON'T WORRY ABOUT COLORING THEM HERE!!!!
for (var row = 0; row < MAXROWS; row++) {
for (var col = 0; col < MAXCOLS; col++) {
// CREATE A DIV HTML ELEMENT CALLED CELL
var cell = document.createElement("div");
// SET ITS CSS CLASS TO CELL
cell.setAttribute("class", "cell");
// GIVE EACH OF THE CREATED DIVS A UNIQUE ID
// BASED ON THE ROW# AND COL#
// EXAMPLE : <div id="c-1-2" class="cell"></div>
// In this example, row = 1 and col = 2
cell.setAttribute("id", "c-" + row + "-" + col);
// !!!!! ADD A CLICK HANDLER TO EACH OF THE INDIVIDUAL DIVS
cell.addEventListener("click", cellClick, false);
// ADD THE DIV HTML ELEMENT TO THE STAGE
stage.appendChild(cell);
// POSITION THE CELL IN THE CORRECT PLACE
// WITH 10 PIXELS OF SPACE AROUND IT
cell.style.width = SIZE + "px";
cell.style.height = SIZE + "px";
cell.style.top = row * (SIZE + SPACE) + "px";
cell.style.left = col * (SIZE + SPACE) + "px";
}
}
colorPattern();
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
// FUNCTION DECLARATIONS
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
function blankPattern() {
// ***********************************************************************
// This function creates a new 2D array based on the size of the MAXROWS and MAXCOLS
// All cells of the array are initialized to 0
// The function RETURNS this new 2D array back to the calling function
// ***********************************************************************
// CREATE A LOCAL VARIABLE TO HOLD THE 2D ARRAY
var newPattern = [];
// LOOP THROUGH ALL THE ROWS
for (var row = 0; row < MAXROWS; row++) {
// EACH ROW OF THE ARRAY.. .IS ALSO AN ARRAY... SO INITIALIZE IT TO BE ONE
newPattern[row] = [];
// LOOP THROUGH ALL THE COLUMNS OF THE ARRAY
for (var col = 0; col < MAXCOLS; col++) {
// INITIALIZE ALL THE CELL VALUES TO BE 0
newPattern[row][col] = 0;
}
}
// RETURN THIS NEW ARRAY BACK TO THE CALLING FUNCTION
return newPattern;
}
function colorPattern() {
// ***********************************************************************
// This function uses the GLOBAL VARIABLE "pattern" to color the divs
// ***********************************************************************
for (var row = 0; row < MAXROWS; row++) {
for (var col = 0; col < MAXCOLS; col++) {
var cell = document.querySelector("#c-" + row + "-" + col);
// COLOR THE CELL IF IT'S ARRAY VALUE IS "1"
if (pattern[row][col] === 0) {
cell.innerHTML = "";
} else if (pattern[row][col] === 1) {
cell.innerHTML = "X";
} else if (pattern[row][col] === 2) {
cell.innerHTML= "O";
}
}
}
}
function cellClick() {
// RIP APART THE DIV ID THAT WAS CLICKED ON
// WERE HIDING THE ROW AND COLUMN IN THE ID
// THE FORMAT OF THE ID IS "C-ROW#-COL#"
// EXAMPLE : <div id="c-1-2" class="cell"></div>
// In this example, row = 1 and col = 2
var zpos;
thisid = "0-1"
// THE "this" KEYWORD RETURNS THE HTML ELEMENT THAT WAS CLICKED ON
var thisid = this.id;
zpos = thisid.indexOf("-");
thisid = thisid.substr(zpos+1);
zpos = thisid.indexOf("-");
var thisRow = thisid.substr(0,zpos);
var thisCol = thisid.substr(zpos+1);
// now that we have the row and column for this div... change the array
if (pattern[thisRow][thisCol] === 0) {
pattern[thisRow][thisCol] = 1;
}
else if (pattern[thisRow][thisCol] === 1) {
pattern[thisRow][thisCol] = 2;
}
else {
pattern[thisRow][thisCol] = 0;
}
colorPattern();
}
function clickHandler ()
{
pattern = blankPattern();
}
</script>
</body>
</html>

This worked for me.
function clickHandler() {
pattern = blankPattern();
colorPattern();
}

Related

Random generated images inside a table disappear

Problem
I tried to randomly generate the position of two images( the images of the characters) in a table td, but sometimes they wouldn't show. One of them or both would just disappear. Try to loading more times (from 1 to 5) the pen to let the bug occur.
Pen
Here is all the code: penHere
Interested functions
How the table\map is building?
it's a 2d array random generated, something like this:
map = [[1,1,1,1,0],
[1,0,0,0,0],
[1,0,1,1,1],
[1,0,0,0,1],
[1,1,1,0,1]]
After I build the map in the table with this one:
function mapGenerate(map){
//loop the 2d array map and change the number with the appropriate img
for(var i = 0; i < map.length; i++) {
var innerArrayLength = map[i].length;
for(var j = 0; j<innerArrayLength; j++){
if(map[i][j] === 0){
map[i][j]="<div class=\"tile\"><img class=\"walkable\" src=\"https://image.ibb.co/bGanFz/floor_Resized.png\"></div>";
}else{
map[i][j]="<img class=\"nonWalkable\" src=\"https://image.ibb.co/m9s1az/volcanoresize.png\">";
}
;
}
$("#tableGame").append("<tr><td>"+ map[i].join('</td><td>') + "</td></tr>")
}
}
with the function below i select the coordinate ( they are corrects, i check it several times in the console)
function placeCharAndItem(char){
let rowCoord= mapA.length;
let cellCoord = mapA[1].length;
//this object is to save 2 random number, the row and the cell
let coord={
row: Math.floor(Math.random() * rowCoord),
cell: Math.floor(Math.random() * cellCoord)
};
//I need this 2 variables to check if the tiles is a correct one
let toCheck = mapA[coord.row][coord.cell];
let check= toCheck.search('nonWalkable');
//if it's not correct(you found the sub-string "non-
//walkable"), this while loop have to generate random new
//coordinates.
while(check != -1){
coord.row=Math.floor(Math.random() * rowCoord);
coord.cell=Math.floor(Math.random() * cellCoord);
toCheck = mapA[coord.row][coord.cell];
check= toCheck.search('nonWalkable');
};
place(coord, char);
};
and finally, after i have 2 valid coordinates i can show the character:
function place(coord, char){
console.log('sei entrato nella funzione place');
var charImage = $("<img>").attr("src", char.image).addClass('char');
var row = $($("#tableGame tr")[coord.row]);
var cell = $($("td", row)[coord.cell]);
var tile = $($(".tile", row)[coord.cell]);
tile.prepend(charImage);
};
these are the css regarding the table and the image char:
#tableGame .td{
position: relative;
}
.char{
z-index: 1000;
}
#tableGame .char {
position: absolute;
}
table{
background-color: black;
border-collapse: collapse;
border: 2px solid white;
box-shadow: 1px 1px 30px white;
}
tr{
border: 0px;
padding: 0px;
margin:0px;
}
td{
border: 0px;
padding: 0px;
margin:0px;
}
I don't understand why sometimes one or both of the images, disappear, any kind of help will be really appreciated.
Assume the map =
[[1,1,1,1,0],
[1,0,0,0,0],
[1,0,1,1,1],
[1,0,0,0,1],
[1,1,1,0,1]]
and coord.row = 0, coord.cell = 4, then $(".tile", row) would be a jQuery object within only 1 .tile. It would set tile to undifined and won't prepend the image.
function place(coord, char){
console.log('sei entrato nella funzione place');
var charImage = $("<img>").attr("src", char.image).addClass('char');
var row = $($("#tableGame tr")[coord.row]);
var cell = $($("td", row)[coord.cell]);
var tile = $($(".tile", row)[coord.cell]);
tile.prepend(charImage);
};
So I think you can replace var tile = $($(".tile", row)[coord.cell]); with var tile = $(".tile", cell);.
function place(coord, char){
console.log('sei entrato nella funzione place');
var charImage = $("<img>").attr("src", char.image).addClass('char');
var row = $($("#tableGame tr")[coord.row]);
var cell = $($("td", row)[coord.cell]);
// will out of bounds if the coord.cell is greater than the jQuery object $(".tile", row)
// var tile = $($(".tile", row)[coord.cell]);
var tile = $(".tile", cell);
tile.prepend(charImage);
};

Javascript function does not run after a function that I created

I am trying to develop a pretty simple and straight forward website. I have a table and a user can fill information in the input="text" fields. I add rows with the plus button that triggers the insertRow() function and remove rows with removeRow() function dynamically. The wipe button removes every text from input="text" fields. When I click the proceed button, the function proceed() is triggered which rebuilds the above table in a new one below. After the rebuild, I add the text from the fields and then, run the removeButtons() function to remove all the buttons from the right side of the tables.
The problem is that I run the removeButtons() inside the proceed() function but the removeButtons() does not get executed. I can not seem to find what is wrong even though I spend quite some time trying to solve the problem, that is why I am requesting help from people with much more experience than me. I know probably the problem is in the proceed() function but I tried several things from which none solved my problem.
My code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.btndiv {
position: relative;
top: -20px;
}
.btn {
position: absolute;
right: -30px;
width: 20px;
height: 20px;
background-image: url(minus.jpg);
cursor: pointer;
}
.btnPlus {
position: absolute;
right: -60px;
width: 20px;
height: 20px;
background-image: url(plus.jpg);
cursor: pointer;
}
.hideP {
display: none;
}
table,
td,
th {
border: 1px solid #ddd;
}
table {
border-collapse: collapse;
}
</style>
<script>
function insertRow() {
//>>> Inserting a row and a div that holds the buttons on every last cell in each row
var table = document.getElementById("myTable");
var count = document.getElementById("myTable").rows.length;
var row = table.insertRow(count);
var cell = 0;
while (cell <= 6) {
var cl = row.insertCell(cell);
cl.innerHTML = "<input type='text' />";
if (cell == 6) {
cl.innerHTML = "<input type='text' /><div class='btndiv'><div class='btn' onclick='deleteRow(this.id)'></div><div class='btnPlus' name='plus' onclick='insertRow()'></div></div>";
}
cell++;
}
hidePlus();
resetIds();
}
function deleteRow(theId) {
//>>> Deleting a row
var count = document.getElementById("myTable").rows.length;
if (count == 3) {
alert("The table must have at least one row!");
} else {
theId++;
theId++;
document.getElementById("myTable").deleteRow(theId);
hidePlusDelete();
resetIds();
}
}
function resetIds() {
//>>> Resetting the ids of my buttons dynamically (when inserting or removing row)
var count = document.getElementById("myTable").rows.length;
var x = document.getElementsByClassName("btn");
var y = 0;
var temp;
while (y <= count) {
temp = x[y];
temp.setAttribute("id", y);
y++;
}
}
function hidePlus() {
//>>> Hiding all plus buttons in every row except the last one on the right side of the minus button
var count = document.getElementById("myTable").rows.length;
if (count > 3) {
var x = document.getElementsByClassName("btnPlus");
var xlength = x.length;
var xlengthnew = xlength - 1;
var y = 0;
var temp;
while (y < xlengthnew) {
temp = x[y];
temp.setAttribute("class", "hideP");
y++;
}
}
}
function hidePlusDelete() {
var count = document.getElementById("myTable").rows.length;
if (count >= 3) {
var x = document.getElementsByClassName("hideP");
var xlength = x.length;
var xlengthnew = xlength - 1;
var y = 0;
var temp;
if (y === xlengthnew && count < 3) {
temp = x[y];
temp.setAttribute("class", "btnPlus");
}
}
}
function clearTable() {
//>>> Clear all input="text" fields
var inp = document.getElementsByTagName('input');
for (var i in inp) {
if (inp[i].type == "text") {
inp[i].value = "";
}
}
}
function proceed() {
//>>> Get text from text boxes and store them in the text variable
//>>> Counter variable to get the number of input="text" fields
var text = "";
var count = 0;
var inp = document.getElementsByTagName("input");
for (var i in inp) {
if (inp[i].type == "text") {
text += inp[i].value;
text += ";";
count++;
}
}
//>>> Store the HTML code from myTable in data variable
//>>> Put the HTML code in newTable
var data = document.getElementById("myTable").innerHTML;
document.getElementById("newTable").innerHTML = data;
//>>> Splitting my text in parts
//>>> Put the text in the input="text" of newTable
var temp = 0;
var counter = 0;
var tempor;
var temporary;
var values = text.split(";");
var p2inp = document.getElementsByTagName("input");
for (var c in p2inp) {
if (p2inp[c].type == "text") {
temp = counter + count + 2;
tempor = p2inp[temp];
temporary = values[counter]
tempor.value = temporary;
//inp[temp].setAttribute("readonly", "readonly");
//inp[temp].setAttribute("disabled", "disabled");
counter++;
}
}
//>>> Hiding buttons from the tables
//>>> The buttons are divs modified to look like buttons with css
removeButtons();
}
function removeButtons() {
//>>> Adding the css class hideP (display="none")
alert("in remove buttons");
var divcount = document.getElementsByClassName("btndiv").length;
alert(divcount);
var divcounter = 0;
var divtemp = 0;
var divinp = document.getElementsByClassName("btndiv");
while (divcounter <= divcount) {
divtemp = divinp[divcounter];
divtemp.setAttribute("class", "hideP");
divcounter++;
}
}
window.onload = insertRow;
</script>
</head>
<body>
<table id="myTable" style="width: 50%">
<col>
<colgroup span="2"></colgroup>
<colgroup span="2"></colgroup>
<tr>
<th colspan="1" rowspan="2">Name, strength and form of medicine</th>
<th colspan="1" rowspan="2">What it's for</th>
<th colspan="4" scope="colgroup">How much to take, when</th>
<th colspan="1" rowspan="2">Extra instructions</th>
</tr>
<tr>
<th scope="col">Breakfast</th>
<th scope="col">Midday meal</th>
<th scope="col">Evening meal</th>
<th scope="col">Bed Time</th>
</tr>
</table>
<br/>
<input type="image" src="whipe.png" onclick="clearTable()" width="50px" height="50px" />
<input type="image" src="go.png" onclick="proceed()" width="50px" height="50px" />
<br/>
<br/>
<br/>
<table id="newTable" style="width: 50%"></table>
</body>
</html>
Your problem (maybe) is this loop, if you comment it out, the desired function will run, so start search for an error here, or from the used variables in your loop:
for (var c in p2inp) {
if (p2inp[c].type == "text") {
temp = counter + count + 2;
tempor = p2inp[temp];
temporary = values[counter]
tempor.value = temporary;
//inp[temp].setAttribute("readonly", "readonly");
//inp[temp].setAttribute("disabled", "disabled");
counter++;
}
}
And as others said, always check for errors in the console.
Also I recommend to try start to debug your javascript.

Continuously adding arrays to a 2D array

Every time I click on a cell in a grid, it logs an array of [rows,column] of the cell into a variable, either bla (for black) or whi (for white). However, the next time I click on a cell, it changes the variable. For example, I click on a cell and variable whi is [1,2] then I click on another cell, variable bla is [2,2] and after that, I click on a third cell and variable whi is changed from [1,2] (from the original click) to [3,2]. (I made up random numbers for this). I want to create two 2D arrays, one for the variable bla and one for the variable whi. Using my example, one of the 2D arrays should be [[1,2],[3,2]] (for the white cells) and the other one should be [[2,2]] (for the black cells)
Test out the code:
var white=true;
function generateGrid( rows, cols ) {
var grid = "<table>";
for ( row = 1; row <= rows; row++ ) {
grid += "<tr>";
for ( col = 1; col <= cols; col++ ) {
grid += "<td></td>";
}
grid += "</tr>";
}
return grid;
}
$( "#tableContainer" ).append( generateGrid( 10, 10) );
$( "td" ).click(function() {
$(this).css('cursor','default');
var index = $( "td" ).index( this );
var row = Math.floor( ( index ) / 10) + 1;
var col = ( index % 10) + 1;
var $td = $(this);
if ($td.data('clicked'))
return;
if (white===true){
var whi=[row,col]; //I want to log the array for whi into a 2D array
console.log("white coord is "+whi);
} else {
var bla=[row,col]; //I want to log this array into another 2D array
console.log("black coord is "+bla);
}
$td.data('clicked', true);
$td.css('background-color', white ? 'white' : 'black');
white = !white;
});
html{
background-color:#7189ea;
}
td {
border: 1px solid;
width: 25px;
height: 25px;
border-radius:100%;
}
table {
border-collapse: collapse;
}
<link type="text/css" rel="stylesheet" href="stylesheet.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="tableContainer"></div>
Initialize whi and bla as arrays and push [row,col] to them - see demo below:
var white = true;
var whi = [];
var bla = [];
function generateGrid(rows, cols) {
var grid = "<table>";
for (row = 1; row <= rows; row++) {
grid += "<tr>";
for (col = 1; col <= cols; col++) {
grid += "<td></td>";
}
grid += "</tr>";
}
return grid;
}
$("#tableContainer").append(generateGrid(10, 10));
$("td").click(function() {
$(this).css('cursor', 'default');
var index = $("td").index(this);
var row = Math.floor((index) / 10) + 1;
var col = (index % 10) + 1;
var $td = $(this);
if ($td.data('clicked'))
return;
if (white === true) {
whi.push([row, col]);
} else {
bla.push([row, col]);
}
$td.data('clicked', true);
$td.css('background-color', white ? 'white' : 'black');
white = !white;
});
$('#getarr').click(function(){
console.log("white arr: ", whi);
console.log("black arr: ", bla);
});
html {
background-color: #7189ea;
}
td {
border: 1px solid;
width: 25px;
height: 25px;
border-radius: 100%;
}
table {
border-collapse: collapse;
}
<link type="text/css" rel="stylesheet" href="stylesheet.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="tableContainer"></div>
<button id="getarr">Get array</button>

How to create board NxN using JavaScript and jQuery

I am trying to create board game (like chess board game) with JavaScript.
When I tried to do it this is what happened:
The <tr> got closed immediately with </tr>, same thing with <table> </table>
I tried to replace the append() method with appendTo() or add() but it didn't help
This is my JavaScript code:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize) {
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--) {
$("#board").append("<tr>");
for(var col = 0; col < maxCol ; col++) {
$("#board").append("<td>" + num + "</td>");
num++;
}
$("#board").append("</tr>");
}
$("#board").append("</table>");
}
CSS:
td {
width: 32px;
height: 32px;
cursor: pointer;
text-align: center;
border: 2px solid blue;
}
.redborder {
background-color: red;
color: white;
}
.blueborder {
background-color: blue;
color: white;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/board.css' />
<script type="text/javascript" src="jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="Scripts/board.js"></script>
</head>
<body>
<p> <center><h3><font size="20" color="black"> Board Game</font></h3></center></p>
<div>
<div id="board">
<div class="cell">
</div>
</div>
</div>
</body>
</html>
This happens because jQuery append() method not supporting only closing tags and trying to close tags if they wasn't closed in provided param. To solve this you need to assign your append() result to some variable, for example:
var myTable = $("<table oncontextmenu=\"return false\"></table>").appendTo("#board");
and then append your rows to this var:
var myRow = $("<tr></tr>").appendTo( myTable );
Same with columns:
myRow.append("<td>" + num + "</td>");
By using appendTo method you will be able to get newly created elements.
So your final code should look like:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize) {
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
var myTable = $("<table oncontextmenu=\"return false\"></table>").appendTo("#board");
for (var row = maxRow - 1; row >= 0; row--) {
var myRow = $("<tr></tr>").appendTo(myTable);
for (var col = 0; col < maxCol; col++) {
myRow.append("<td>" + num + "</td>");
num++;
}
}
}
The others have supplied you with why this is happening but I thought I might give an example of how you might make better use of css and more recent dom usage.
Fiddle: http://jsfiddle.net/np62shu6/1/
But the basic idea is to define the number of cells, then write out a series of divs that have a 20% float value. In the end you have a chess board with a cell data attribute.
HTML:
<div id="game">
</div>
CSS:
.cell{
width:20%;
float:left;
text-align:center;
}
.odd{
background:#eee;
}
JS (assumed you place this in a load handler):
var cells = 25;
var cell;
var h;
for(var i = 1; i <= cells; i ++)
{
cell = $('<div>').addClass('cell').attr('data-cell', i).text(i);
if(i % 2 == 1)
cell.addClass('odd');
$('#game').append(cell);
}
h = $('.cell:last-of-type').width();
$('.cell').css({height: h, lineHeight: h + 'px'});
As others have said, append is a sequential method, so calling it one after the other will just keep dropping things in the DOM. But you can create elements, then add things to those elements using append, then use append to add that whole group to another...
My example does not show this. My example is just an alternative to what you wrote. I would not do it the way you are doing it is all.
Another slight side note - chess boards have 64 cells (8 x 8), but I left it at 25 because your example did this.
When you append a tag with jQuery it doesn't work like appending text to a HTML string. Instead it creates the dom element. Try something like this instead, notice the absence of closing tags and td is appended directly to the latest tr:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--)
{
$("#board table").append("<tr>");
for(var col = 0; col < maxCol ; col++)
{
$("#board tr:last").append("<td>" + num + "</td>");
num++;
}
}
}
The error is here:
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--)
{
#here
$("#board").append("<tr>");
for(var col = 0; col < maxCol ; col++)
{
#here
$("#board").append("<td>" + num + "</td>");
num++;
}
$("#board").append("</tr>");
}
$("#board").append("</table>");
}
You are appending each element to the #board instead of properly nesting them. try keeping the created elements in variables, and do nesting:
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$tableelement = $("<table oncontextmenu=\"return false\"></table>");
$("#board").append($tableelement);
for(var row = maxRow - 1; row >= 0 ; row--)
{
#here
$rowelement = $("<tr></tr>");
$tableelement.append($rowelement);
for(var col = 0; col < maxCol ; col++)
{
#here
$rowelement.append("<td>" + num + "</td>");
num++;
}
}
}
Reason: certain browsers will immediately try to fix malformed HTML, and in the middle of the execution, the items are malformed while you insert it, and are wellformed after you finish. in the middle -this function's execution is not atomic- the code is malformed and the browser tries to fix it by closing the tags you add. That's why you need to add elements by nesting -opening and closing the tags for them beforehand-
$(function() { //on load
var boardSize = 5;
printBoard(boardSize);
});
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize),
maxCol = maxRow;
var $table = $("<table oncontextmenu='return false'></table>").appendTo($("#board"));
for(var row = 1; row <= maxRow; row++)
{
var $row = $("<tr/>").appendTo($table);
for(var col = 1; col <= maxCol; col++)
{
$row.append("<td>" + (row*col) + "</td>");
}
}
}
td {
width: 32px;
height: 32px;
cursor: pointer;
text-align: center;
border: 2px solid blue;
}
.redborder {
background-color: red;
color: white;
}
.blueborder {
background-color: blue;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> <center><h3><font size="20" color="black"> Board Game</font></h3></center></p>
<div>
<div id="board">
<div class="cell">
</div>
</div>
</div>
Side note: You don't have to append the closing tags manually...
This is way easier and cleaner if you just learn JavaScript and work in the DOM.
function makeBoardWithoutJQuery(xs, ys) {
var table = document.createElement('table');
var tbody = document.createElement('tbody');
for (var y=0; y<ys; ++y) {
var tr = document.createElement('tr');
for (var x=0; x<xs; ++x) {
var td = document.createElement('td');
td.innerHTML = (y*xs) + x;
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
return table;
}

chess board using javascript and dom

I'm trying to create a chessboard just like this.
I did create a table And don'r know how to colour it. A also need to print the board name (like A1, A2, ... H8) and be able to pust any figuere in any of the cell.
For start this is the code to create a table:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ChessBoard</title>
<script type="text/javascript">
function CreateTable(){
var poz = document.getElementById('space');
// createing table adn inserting into document
tab = document.createElement('table');
poz.appendChild(tab);
tab.border = '5';
for (var i = 0; i < 8; i++){
// creating row and inserting into document
var row = tab.insertRow(i);
for(var j = 0; j < 8; j++){
// creating cells and fill with data (numbers)
var cell = row.insertCell(j);
cell.innerHTML = i*j;
cell.style.backgroundColor = 'blue';
cell.style.color = 'white';
cell.style.height = '50px';
cell.style.width = '50px';
};
};
}
</script>
</head>
<body onload="CreateTable()" id ="space">
</body>
</html>
How do i fill specific cell with figure (like A3, E5, H8, ...)? Figure are imgages.
Part 2:
I did create a board with your help.
Now I'm trying to do some more from this code.
How do I put several different images into several cells? I'm trying to get right working code, but with no success. This images should appear when the tabel will be loaded (when i press button CreateTable).
I try to create with this code:
In this point I would like to put figures on board. When i create table it should be blank. Then there will be buttons to add figures. At the beginning for each different figure own button
something like this:
function addKing(idStr){
cell = document.getElementById(idStr);
if(cell != null){
// works for color, doesn't work for images!!
// cell.style.backgroundColor = 'red';
cell.src = 'http://akramar.byethost8.com/images/SplProg/DN3/images/50px/king_m.png'
}
}
Button addKing in html:
<button id="king" onclick="addKing(prompt('Insert field'))">Add King</button>
upgrading previousu code to even better if i can put all together and select which one I like to insert (promtpt window 1: what figure:'king, queen, ...', prompt window 2: on what position would you like to insert: 'A1, B3, ...')).
function addImage (type, position){
var img = ??
}
When I pres button add image the prompt window should appear and ask for type (king, queen, root, ...) and location (A1, B4, ...) (for further update perhaps even color (black or white) but let build step by step).
All tis chessboard I would like to build just in javascript and with dom.
link to not working exaple: jsfiddle
Assuming you need to support only modern browsers, the chess-board is entirely do-able with CSS using counters, and generated-content:
table {
empty-cells: show;
}
td {
width: 2em;
height: 2em;
line-height: 2em;
text-align: center;
border: 1px solid #000;
}
tbody tr:nth-child(odd) td:nth-child(even),
tbody tr:nth-child(even) td:nth-child(odd) {
color: #fff;
background-color: #00f;
}
tbody tr:nth-child(even) td:nth-child(even),
tbody tr:nth-child(odd) td:nth-child(odd) {
background-color: #999;
}
tbody {
counter-reset: rowNumber;
}
tr {
counter-increment: rowNumber;
counter-reset: cellNumber;
}
td {
counter-increment: cellNumber;
}
td::before {
content: counter(rowNumber, upper-alpha) counter(cellNumber, decimal);
}
JS Fiddle demo.
The above tested in Chromium 24 and Firefox 19, both on Ubuntu 12.10.
And for a JavaScript approach:
var chess = {
createBoard: function (dimension) {
if (!dimension || isNaN(dimension) || !parseInt(dimension, 10)) {
return false;
} else {
dimension = typeof dimension === 'string' ? parseInt(dimension, 10) : dimension;
var table = document.createElement('table'),
tbody = document.createElement('tbody'),
row = document.createElement('tr'),
cell = document.createElement('td'),
rowClone,
cellClone;
table.appendChild(tbody);
for (var r = 0; r < dimension; r++) {
rowClone = row.cloneNode(true);
tbody.appendChild(rowClone);
for (var c = 0; c < dimension; c++) {
cellClone = cell.cloneNode(true);
rowClone.appendChild(cellClone);
}
}
document.body.appendChild(table);
chess.enumerateBoard(table);
}
},
enumerateBoard : function (board) {
var rows = board.getElementsByTagName('tr'),
text = document.createTextNode(),
rowCounter,
len,
cells;
for (var r = 0, size = rows.length; r<size; r++){
rowCounter = String.fromCharCode(65 + r);
cells = rows[r].getElementsByTagName('td');
len = cells.length;
rows[r].className = r%2 == 0 ? 'even' : 'odd';
for (var i = 0; i<len; i++){
cells[i].className = i%2 == 0 ? 'even' : 'odd';
cells[i].appendChild(text.cloneNode());
cells[i].firstChild.nodeValue = rowCounter + i;
}
}
}
};
chess.createBoard(10);
JS Fiddle demo.
You can tie an ID to the cell, and then use that ID to reference and updated the background as needed. Here is one example using your code: http://jsfiddle.net/7Z6hJ
function CreateTable(){
var poz = document.getElementById('space');
// createing table adn inserting into document
tab = document.createElement('table');
poz.appendChild(tab);
tab.border = '5';
for (var i = 0; i < 8; i++){
// creating row and inserting into document
var row = tab.insertRow(i);
for(var j = 0; j < 8; j++){
// creating cells and fill with data (numbers)
var cell = row.insertCell(j);
var idStr = String.fromCharCode(97 + i).toUpperCase() + (j+1);
cell.innerHTML = idStr;
cell.id = idStr;
cell.style.backgroundColor = 'blue';
cell.style.color = 'white';
cell.style.height = '50px';
cell.style.width = '50px';
};
};
}
function updateRow(idStr)
{
cell = document.getElementById(idStr);
if(cell != null)
{
cell.style.backgroundColor = 'red';
}
}
As some have mentioned, there is probably a better way to go about this (using css and jQuery, etc) but this answer sticks with what you have so far.
Create a new variable inside the top loop to save the "letter" name of the row (eg. A, B, C).
// creating row and inserting into document
var row = tab.insertRow(i);
var row_letter = String.fromCharCode(65 + i);
Then in the second loop combine the row name and column number.
cell.innerHTML = row_letter + j;
Actually, you need to do some math for correctly coloring and adding labels. Here is the part of code for doing magic:
1 cell.innerHTML = String.fromCharCode(65 + i) + (j + 1);
2 if((i+j)%2){ cell.style.backgroundColor = 'white'; }
3 else{ cell.style.backgroundColor = 'blue'; }
4 cell.style.color = 'black';
5 cell.style.height = '50px';
6 cell.style.width = '50px';
Let me explain. In first line, you take constant 65, which is ASCII code for letter 'A'. While you change the letter by rows, you add i counter to it, so you get 65+0, 65+1, ..., 65+7. Their ASCII equivalents (which you get with String.fromCharCode()) are A, B, ..., H. Now when you have that letter, easily add number of cell to it (j + 1). You can remove '1' and leave just j and make inner loop go from 1 to 8.
Lines 2, 3: Colors are alternating - every second row have the same color. So, just test if is i+j dividable by 2.
For adding figure, you have to make some function that will do cell.innerHTML = <SOME IMAGE>. But, I guess, it's for second question.
Hope I helped you understand the logic.
I case if someone is looking for a way to visualize a chessboard using JS (as I was doing and accidentally came to this question), here is an excellent JS library to do this.
It can create something like this
and much more in no time just by doing the following:
JavaScript
var ruyLopez = 'r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R';
var board = new ChessBoard('board', ruyLopez);
HTML
<div id="board" style="width: 400px"></div>

Categories