Simple JavaScript chess board - javascript

Could anyone give me a hint on how to generate a chess board (8x8) using JavaScript, using a table tags or ?
I've got the following so far:
<DOCTYPE html>
<html>
<head>
<style>
div
{
border:1px solid black;
width:20px;
height:20px;
}
</style>
</head>
<body>
<script type="text/javascript">
// create a chess table 8x8.
var count = 0;
while (count < 64)
{
if (count % 2 == 0)
{
if (count % 8 == 0 && count !=0)
{
document.write('<br/><div style="background-color:#000000;float:left;">&nbsp</div>');
}
else
{
document.write('<div style="background-color:#000000;float:left;">&nbsp</div>');
}
}
else
{
document.write('<div style="background-color:#FFFFFF;float:left;">&nbsp</div>');
}
/*
*/
count++;
}
</script>
</body>
</html>
I tried to assign black and white to each odd and even number respectively, but it doesn't work this way.
Thank you in advance.

I can not test it at this moment but this should work. This code creates a 8x8 table in which black cells are tagged with "black" class and white cells are tagged with "white" class. Use CSS to give them color. I hope it helps.
var table = document.createElement("table");
for (var i = 1; i < 9; i++) {
var tr = document.createElement('tr');
for (var j = 1; j < 9; j++) {
var td = document.createElement('td');
if (i%2 == j%2) {
td.className = "white";
} else {
td.className = "black";
}
tr.appendChild(td);
}
table.appendChild(tr);
}
document.body.appendChild(table);

At some point for me, this became code golf:
http://jsfiddle.net/4Ap4M/
JS:
for (var i=0; i< 64; i++){
document.getElementById("mainChessBoard").appendChild(document.createElement("div")).style.backgroundColor = parseInt((i / 8) + i) % 2 == 0 ? '#ababab' : 'white';
}
HTML:
<div id="mainChessBoard">
</div>
CSS:
#mainChessBoard
{
width:160px;
height:160px;
border:1px solid black;
}
div
{
width:20px;
height:20px;
float:left;
}

This is the basic foundation to build your chess board.
You can check out the chess board pattern in the console.
var chessBoard = function(size){
var hash = '#'
var space = '_'
for (var i = 0; i < size; i++)
{
hash += '\n'
for (var j = 0; j < size; j++)
{
if((i +j) % 2 == 0)
{
hash += space
}
else
{
hash += "#"
}
};
};
console.log(hash)
}(8)

You can generate boards of any size you want, and this way is pretty easy to change the size of the squares and the colors. you don't need to change anything else.
It is good practice to keep appearance on the stylesheet.
Also don't use document.write
http://jsfiddle.net/YEJ9A/1/
Javascript
var x=8;
var y=8;
var chessBoard = document.getElementById("chessBoard");
for (var i=0; i<y; i++){
var row = chessBoard.appendChild(document.createElement("div"));
for (var j=0; j<x; j++){
row.appendChild(document.createElement("span"));
}
}
CSS
#chessBoard span{
display: inline-block;
width: 32px;
height: 32px;
}
#chessBoard div:nth-child(odd) span:nth-child(even),
#chessBoard div:nth-child(even) span:nth-child(odd){
background-color: black;
}
#chessBoard div:nth-child(even) span:nth-child(even),
#chessBoard div:nth-child(odd) span:nth-child(odd){
background-color: silver;
}

May be you want to do it with divs, not with the table. So here is the solution for it.
$(document).ready(function() {
for (var i = 1; i <= 8; i++) {
var divRow = $("<div>", {
class: "row",
});
for (var j = 1; j <= 8; j++) {
var div = $("<div>", {
class: "square"
});
if (i % 2 == j % 2) {
$(div).addClass("white");
} else {
$(div).addClass("black");
}
divRow.append(div);
}
$("#board").append(divRow);
}
});
#board {
margin: 0;
width: 256px;
height: 256px;
border: solid 1px #333;
}
#board .row {
margin: 0;
}
.square {
height: 32px;
width: 32px;
background: #efefef;
float: left;
}
.square.white {
background: #fff;
}
.square.black {
background: #333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="board"></div>

A little modernization, using css variables, css attr() and dataset attributes.
This allows to tweak themes, and keep stuffs simple.
const cols = {0:"A", 1:"B", 2:"C", 3:"D", 4:"E", 5:"F", 6:"G", 7:"H"}
const table = document.createElement("table");
table.className = "board";
for (let i = 1; i < 9; i++) {
let tr = document.createElement('tr');
tr.dataset.line = i
for (let j = 1; j < 9; j++) {
let td = document.createElement('td');
td.dataset.col = cols[j-1];
td.dataset.line = i;
td.className = (i%2 === j%2) ? "white square" : "black square";
tr.appendChild(td);
}
table.appendChild(tr);
}
document.querySelector("div").appendChild(table);
:root {
--size: 640px;
--backcolor: darkslategray;
--dark: grey;
--light: white;
--legend: azure;
--hover: lightgreen
}
.board {
width: var(--size);
height: var(--size);
border: 32px solid;
border-color: var(--backcolor);
border-radius: 0.2rem;
}
.square {
border: 1px black solid;
}
.white{
background: var(--light);
}
.black{
background: var(--dark)
}
.board tr::before {
content: attr(data-line);
position: absolute;
margin: 1.8rem 0 0rem -1.5rem;
font-size: larger;
color: var(--legend);
}
.board tr::after {
content: attr(data-line);
position: absolute;
margin: 1.8rem 0 0rem 0.8rem;
font-size: larger;
color: var(--legend);
}
.board tr:first-child > td::before {
content: attr(data-col);
position: absolute;
margin: -4rem 0 0rem 1.6rem;
font-size: larger;
color: var(--legend);
}
.board tr:last-child > td::after {
content: attr(data-col);
position: absolute;
margin: 2.6rem 0 0rem 1.6rem;
font-size: larger;
color: var(--legend);
}
td:hover {
background: var(--hover);
cursor: pointer
}
<div></div>

The following code will print chess board using only HTML and JavaScript.
<script>
document.write("<table border='1' width='200' height='200'>");
for(var i=1; i<=8; i++)
{
document.write("<tr>");
for(var j=1; j<=8; j++)
{
if((i+j)%2!=0)
{
document.write("<td bgcolor='white'></td>");
}
else
{
document.write("<td bgcolor='black'></td>");
}
}
document.write("</tr>");
}
document.write("</table>");
</script>

You should try this one this will really work
<DOCTYPE html>
<html>
<head>
<style>
.chessBoard {
display: inline-block;
border: 2px solid lightGray;
}
.chessBoard div {
line-height: 1px;
}
.chessBoard span {
display: inline-block;
width: 32px;
height: 32px;
background-color: snow;
}
</style>
</head>
<body>
<div class="chessBoard" id="chessBoardNormal"></div>
<div class="chessBoard" id="chessBoardRandom"></div>
<script>
function colorNormal(x, y, color) {
var chessBoard = document.getElementById("chessBoardNormal");
for (var i = 0; i < x; i++) {
var row = chessBoard.appendChild(document.createElement("div"));
for (var j = 0; j < y; j++) {
var span = document.createElement('span');
if (i & 1) { // odd
if (j & 1) { // white
} else { // black
span.style.backgroundColor = color;
}
} else { // even
if (j & 1) { // black
span.style.backgroundColor = color;
}
}
row.appendChild(span);
}
}
}
function colorRandom(x, y) {
colorNormal(8, 8, Math.random() > .5 ? 'black' : '#CFD65C');
}
function getRandomHexColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
colorNormal(8, 8, 'black');
</script>
</body>
</html>

My idea is simple, if row is even then start with white piece otherwise start with black piece.
HTML:
<div id="mainChessBoard"></div>
Javascript:
const fragment = document.createDocumentFragment();
const board = document.getElementById("mainChessBoard");
const size = 8;
for (let i = 0; i < size; i++) {
let start = i % 2 === 0 ? 0 : 1; // if row is even then start with white otherwise start with black;
for (let j = 0; j < size; j++) {
const div = document.createElement('div');
div.classList.add(start === 1 ? "black" : "white");
fragment.appendChild(div);
start = start === 1 ? 0 : 1;
}
}
board.appendChild(fragment);

Here's a plain JS copy-paste solution. I know it's not that clean in terms of conditioning but it does the job comprehensibly and it's quite straight forward. Field size is easily adjustable as well.
const fieldSize = 50;
const whiteField = document.createElement("div");
whiteField.style = `height:${fieldSize}px;width:${fieldSize}px;background-color:white;display:inline-block`;
const blackField = document.createElement("div");
blackField.style = `height:${fieldSize}px;width:${fieldSize}px;background-color:black;display:inline-block`;
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++)
i % 2 === 0 ?
j % 2 === 0 ?
document.body.appendChild(blackField.cloneNode(true)) :
document.body.appendChild(whiteField.cloneNode(true)) :
j % 2 === 0 ?
document.body.appendChild(whiteField.cloneNode(true)) :
document.body.appendChild(blackField.cloneNode(true));
document.body.appendChild(document.createElement("br"));
}

We can always think of a better performance, here's the DOM optimized solution using documentFragments -
// main container
let container = document.querySelector("#main");
// a fragment object to store a 2-D mesh of rows and columns
let fragment = new DocumentFragment();
for (let i = 0; i < 8; i++) {
// a fragment object to store a single row with 8 columns
let rowFragment = new DocumentFragment();
for (let j = 0; j < 8; j++) {
// div element for a column
let col = document.createElement("div");
col.style.border = "1px solid";
if ((i + j) % 2 == 0) col.style.background = "black";
else col.style.background = "white";
// adding column in a document fragment
rowFragment.appendChild(col);
}
// adding row in a main fragment
fragment.appendChild(rowFragment);
}
// adding fragment to a DOM one time - this will update the DOM only once
container.appendChild(fragment);
.container {
display: flex;
width: 416px; /* width + horizontal border of each cell ((50 + 2) * 8) */
height: 416px; /* height + vertical border of each cell ((50 + 2) * 8) */
}
div {
flex-wrap: wrap; /* to fit 8 cells in a row as per the width */
width: 50px;
height: 50px;
}
<div class="container" id="main"></div>
Here, the DocumentFragment creates an object of elements we add, but it isn't a part of the active document tree unless we append it to any other DOM node.

Javascript:
var i, j, clas;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
clas = '';
if (j === 0) clas = 'first ';
else if (j === 7) clas = 'last ';
clas += (i % 2 == j % 2) ? 'white' : 'black';
var field = document.createElement('div');
field.className = clas;
document.body.appendChild(field);
}
}
CSS:
div {
float: left;
width: 20px;
height: 20px;
}
.first {
clear: left;
}
.black {
background: black;
}
.white {
background: red;
}
Sample: http://jsfiddle.net/YJnXG/2/

You mean like this?
.... html.....
<table>
<tr>
<script language='javascript'>
<!--
alternate();
//-->
</script>
</tr>
</table>
....more html.....
function alternate()
{
var numOfCells = 6;
var num = 0;
for (i = 0; i < numOfCells ; i++)
{
txt = "<td bgColor='";
txt += (num % 2 == 0) ? 'red' : 'black';
txt += "'>"
document.write(txt);
num++;
}
}
The % sign is mod; it returns the remainder of a division. the "(...) ? ... : ...;" construction is like an if/else. If the condition is true, the first option -- else the second.

Related

How to sort elements on DOM by its inner Text

I have a graph that is rendering its values as a div inside the body element with a class according to their number values. This is working fine. But next I need to sort the divs according to their number values or background color. BUT, it needs to start on the lower left corner of the page and fan out upwards to towards the right as the numbers increase. Basically just like a line graph.
I'd like to stay away from libraries if at all possible.
How would I approach this? Thank you all.
let interval = setInterval(makeDivs, 5);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('body').appendChild(div);
} else {
alert('done');
clearInterval(interval);
sortDivs(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('body').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function sortDivs(){
document.querySelector("body div:last-child").remove();
alert('sorting now...')
}
* { box-sizing: border-box;}
body { width: 100vw; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: end;}
body div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body div.blue { background: aqua; }
body div.green { background: green; }
body div.yellow { background: yellow; }
body div.orange { background: orange; }
body div.red { background: red; }
UPDATE!!!
So I have this so far based on the feed back down below. The problem now is the sorting is only happening laterally and not on an angle (spreading right and to the top).
let interval = setInterval(makeDivs, 10);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('.outPut').appendChild(div);
} else {
clearInterval(interval);
document.querySelector(".outPut div:last-child").remove();
compileArrays(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('.outPut').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function compileArrays(){
let divs = document.querySelectorAll('.outPut div');
let bArr = [], gArr = [], yArr = [], oArr = [], rArr = [];
divs.forEach( (d) => {
if( d.classList.contains('blue') ){ bArr.push(d) }
if( d.classList.contains('green') ){ gArr.push(d) }
if( d.classList.contains('yellow') ){ yArr.push(d) }
if( d.classList.contains('orange') ){ oArr.push(d) }
if( d.classList.contains('red') ){ rArr.push(d) }
});
let finalArr = sortArray(bArr).concat(sortArray(gArr)).concat(sortArray(yArr)).concat(sortArray(oArr)).concat(sortArray(rArr));
newDom(finalArr);
}
function sortArray(arr){
let newArr = arr;
newArr.sort( (a, b) => {
return a.innerText - b.innerText;
});
return newArr;
}
function newDom(arr){
let b = document.querySelector('.outPut');
b.innerHTML = '';
arr.reverse();
arr.forEach((a) => {
b.appendChild(a);
});
}
* { box-sizing: border-box;}
body { width: 100vw; height: 100vh; margin: 0; padding: 0; display: flex; align-items: flex-end;}
body .outPut { flex: 1; display: flex; flex-wrap: wrap; flex-direction:row-reverse; }
body .outPut div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body .outPut div.blue { background: aqua; }
body .outPut div.green { background: #44df15; }
body .outPut div.yellow { background: yellow; }
body .outPut div.orange { background: orange; }
body .outPut div.red { background: red; }
<div class="outPut"></div>
Supposed you already have a mechanism to organise such DIVs in a grid as shown, the following should give you what you are looking for:
var items = divList.filter((div) => div.nodeType == 1); // get rid of the whitespace text nodes
items.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
Then, place them back in the DOM as needed, example:
for (i = 0; i < items.length; ++i) {
divList.appendChild(items[i]);
}
This worked with the first code example!!!
try this sortDivs function:
function sortDivs() {
document.querySelector("body div:last-child").remove();
alert('sorting now...')
let toSort = document.getElementsByTagName("div")
toSort = Array.prototype.slice.call(toSort, 0)
toSort.sort((a, b) => {
let aord = parseFloat(a.textContent);
let bord = parseFloat(b.textContent);
return bord - aord;
})
document.body.innerHTML = ""
for(var i = 0, l = toSort.length; i < l; i++) {
document.querySelector('body').appendChild(toSort[i]);
}
}
and in the css file set flex-wrap to wrap-reverse. Hope I could help :)
PS: please, implement some else if instead of doing only if
Here is a small fiddle with my sample code demonstrating a simple solution in pure JavaScript and absolute CSS positioning for what you are trying to achieve. Link
As some pointed out already, there might be a library, that already provides a better and complete solution for this - I did not research if it is so.
Code:
file.js
var container = document.getElementById("container")
var results = [1,2,3,4,5,6,7,8]
//you can pre-calculate the order of the distances
//here already orderdered array [distanec][X-axis][Y-axis]
var distances =[[0,0,0],
[1,1,0],
[1,0,1],
[1.414, 1,1],
[2,0,2],
[2,2,0],
[2.234, 2,1],
[2.234, 1,2]]
for (i = 0; i < results.length; i++){
var newDiv = document.createElement("div")
newDiv.className = "result"
newDiv.innerHTML = results[i]
newDiv.style.left = distances[i][1]*20 + "px"
newDiv.style.bottom = distances[i][2]*20 + "px"
container.appendChild(newDiv)
}
function setColor(element){
// set class based on value - you already have this part
}
style.css
#container {
border: 4px;
border-color: red;
border-style: solid;
height: 200px;
width: 200px;
position: relative;
}
.result{
border: 2px;
width: 20px;
height: 20px;
position: absolute;
border-color: blue;
border-style: solid;
text-align: center;
}
site.html
<div id="container">
</div>
Output:

Add scores grid game JavaScript

I want to add 10 points when blue box goes into brown box.
I tried to set score = 0 and points to add = 10 but it doesn't work.
I alert '+10 points' and it shows me the alert so I guess the problem is the DOM ?!?
Any suggestions ?
Thanks !
let moveCounter = 0;
let score = 0;
let obs = 10;
document.getElementById('score').textContent = '0';
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 49; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var obstacles = [];
while (obstacles.length < 10) {
var randomIndex = parseInt(49 * Math.random());
if (obstacles.indexOf(randomIndex) === -1) {
obstacles.push(randomIndex);
var drawObstacle = document.getElementById('square' + randomIndex);
$(drawObstacle).addClass("ob")
}
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(49 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var drawPone = document.getElementById('square' + randomIndex);
$(drawPone).addClass("p-0")
}
}
var addPoints = $('#score');
$('#button_right').on('click', function() {
if ($(".p-0").hasClass("ob")) {
alert('add +10 points !!!')
addPoints.text( parseInt(addPoints.text()) + obs );
}
moveCounter += 1;
if ($(".p-0").hasClass("ob")) {
}
$pOne = $('.p-0')
$pOneNext = $pOne.next();
$pOne.removeClass('p-0');
$pOneNext.addClass('p-0');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.ob {
background-color: brown;
}
.p-0 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box">
</div>
<div class="move">
<button id="button_right">right</button><br>
</div>
<div id="score">
</div>
Thank you very much! I am new to JavaScript/ JQuery
Thank you very much!
You are trying to change the HTML inside of the div with id "score".
Selecting the css element using $("#id") retrieves the DOM element and not its contents so adding the score directly to it has no consequences.
What you want to do is: update the score variable and then set the HTML inside the div to the score value.
So instead of just:
addPoints += obs
you should
score += obs
addPoints.html(score)

Math.random duplicates numbers JavaScript

I want to randomly assign a class at two boxes.
But even with indexOf(randomIndex) === -1) Math.random is duplicating the numbers.
If you refresh you will see that the boxes are changing classes but sometimes they both have the same class, this should happened.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
var weapon3 = [];
while (weapon3.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weapon3.indexOf(randomIndex) === -1) {
weapon3.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
You are using two different arrays for storing the weapons. Use same array so that the number is not repeated.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
while (weaponTwo.length < 2) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
Better Approach : You can create an array of classes and then shuffle it using this alogrithm. Then you can pop from the array and add to classes one by one.

Visualize JSON data containing XY coordinate location

I have JSON data which includes X-Y grid location, quantity, and color.
[{"x":1,"y":2,"qty":5,"color":"red"},
{"x":2,"y":4,"qty":10,"color":"green"},
{"x":3,"y":1,"qty":15,"color":"green"},
{"x":4,"y":3,"qty":20,"color":"red"}]
I would like to visualize the JSON like this:
Preference is to use something in the Google Visualization API, but I'm open to other solutions. I'm familiar enough with Javascript but wanted something that was a bit more plug/play.
Any ideas on where to begin?
Thanks as always!
My solution is not very elegant, but the idea was just to show how you can use basic Javascript with no additional libraries and just a bare bit of CSS to achieve this. I threw in a couple of additional values with a blue background to test out additional data. You can make it look better with additional CSS - and expand on the feature set here, but just wanted to throw something up that would reproduce the chart in your image.
var data = [{"x":1,"y":2,"qty":5,"color":"red"},
{"x":2,"y":4,"qty":10,"color":"green"},
//{"x":1,"y":4,"qty":8,"color":"blue"},
{"x":3,"y":1,"qty":15,"color":"green"},
//{"x":3,"y":2,"qty":77,"color":"purple"},
//{"x":5,"y":3,"qty":66,"color":"purple"},
//{"x":2,"y":1,"qty":22,"color":"blue"},
{"x":4,"y":3,"qty":20,"color":"red"}];
var chart = document.getElementById('chart');
var rows = 0;
var cols = 0;
// loop through and figure out how many rows and columns we will have
for (var i = 0; i < data.length; i++) {
if (data[i].x > rows) rows = data[i].x;
if (data[i].y > cols) cols = data[i].y;
if (rows > cols) cols = rows;
if (cols > rows) rows = cols;
yCt = rows;
}
drawChart(rows,cols);
function drawChart(rows,cols) {
var e = 0;
var f = 0;
while (e < rows) {
var square = '<div class="square"><div class="header">'+yCt+'</div></div>';
yCt--;
chart.innerHTML = chart.innerHTML + square;
addColumn(e);
e++;
}
if ( e == rows ) {
addHeader()
addValues()
}
}
function addHeader() {
var sq = document.getElementsByClassName('squareCol');
var ct = 0;
for (var i = 0; i < sq.length; i++) {
var element = sq[i];
if (element.getAttribute('data-y') == 1) {
ct++;
var heading = document.getElementById('heading');
heading.innerHTML = heading.innerHTML + '<div class="headerCol">'+ct+'</div>';
}
}
}
function addColumn(rowNumber) {
var row = document.getElementsByClassName('square')[rowNumber]
for (var i = 0; i < cols; i++) {
var x = i +1;
var y = rows - (rowNumber);
var squareCol = '<div class="squareCol" data-x="'+x+'" data-y="'+y+'"></div>';
row.innerHTML = row.innerHTML + squareCol;
}
}
function addValues() {
for (var i = 0; i < data.length; i++) {
var xVal = data[i].x;
var yVal = data[i].y;
var qty = data[i].qty;
var color = data[i].color;
var squares = document.getElementsByClassName('squareCol')
for (var j = 0; j < squares.length; j++) {
var element = squares[j];
if (element.getAttribute('data-x') == xVal && element.getAttribute('data-y') == yVal) {
element.innerHTML = '<div class="qty"><div class="inner">'+qty+'</div></div>'
element.className += ' '+ color;
}
} // end loop squares
}
}
#heading {
position:absolute;
margin-bottom:150px;
margin-left:100px;
width: 100%;
}
.header {
position:absolute;
line-height:4;
vertical-align:text-bottom;
text-align: center;
margin-left:-50px;
font-family:arial;
font-size:1.2rem;
font-weight:bold;
}
.headerCol {
display:inline-block;
border-width: 0;
line-height:3;
text-align: center;
font-family:arial;
font-size:1.2rem;
width: 50px;
font-weight:bold;
}
.square {
height: 50px;
}
.qty {
position: relative;
text-align:center;
line-height:3;
}
.inner {
position:absolute;
text-align:center;
margin:0;
width: 100%;
}
.squareCol {
width: 50px;
height: 50px;
box-shadow: inset 0 0 0 1px black;
display:inline-block;
font-family:arial;
font-size:1.2rem;
font-weight:bold;
}
#chart {
width: 600px;
margin-left:100px;
}
.blue {
background-color: lightblue;
}
.green {
background-color: #92D050;
}
.red {
background-color: #FF0000;
}
.purple {
background-color: violet;
}
<div id="chart"></div>
<div id="heading"></div>

How to add multiple divs with appendChild?

I am trying to make a chessboard using javascript and creating 64 divs with it.
The problem is, that it creates only the first div.
Here is the code:
div {
width: 50px;
height: 50px;
display: block;
position: relative;
float: left;
}
<script type="text/javascript">
window.onload=function()
{
var i=0;
var j=0;
var d=document.createElement("div");
for (i=1; i<=8; i++)
{
for (j=1; j<=8; j++)
{
if ((i%2!=0 && j%2==0)||(i%2==0 && j%2!=0))
{
document.body.appendChild(d);
d.className="black";
}
else
{
document.body.appendChild(d);
d.className="white";
}
}
}
}
</script>
As t-j-crowder has noted, the OP's code only creates one div. But, for googlers, there is one way to append multiple elements with a single appendChild in the DOM: by creating a documentFragment.
function createDiv(text) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(text));
return div;
}
var divs = [
createDiv("foo"),
createDiv("bar"),
createDiv("baz")
];
var docFrag = document.createDocumentFragment();
for(var i = 0; i < divs.length; i++) {
docFrag.appendChild(divs[i]); // Note that this does NOT go to the DOM
}
document.body.appendChild(docFrag); // Appends all divs at once
The problem is, that it creates only the first div.
Right, because you've only created one div. If you want to create more than one, you must call createElement more than once. Move your
d=document.createElement("div");
line into the j loop.
If you call appendChild passing in an element that's already in the DOM, it's moved, not copied.
window.onload=function()
{
var i=0;
var j=0;
for (i=1; i<=8; i++)
{
for (j=1; j<=8; j++)
{
if ((i%2!=0 && j%2==0)||(i%2==0 && j%2!=0))
{
var d=document.createElement("div");
document.body.appendChild(d);
d.className="black";
}
else
{
var d=document.createElement("div");
document.body.appendChild(d);
d.className="white";
}
}
}
}
Although what T.J. Crowder writes works fine, I would recommend rewriting it to the code below, using a documentFragment, like Renato Zannon suggested. That way you will only write to the DOM once.
window.onload = function() {
var count = 5,
div,
board = document.getElementById('board'),
fragment = document.createDocumentFragment();
// rows
for (var i = 0; i < count; ++i) {
// columns
for (var j = 0; j < count; ++j) {
div = document.createElement('div');
div.className = (i % 2 != 0 && j % 2 == 0) || (i % 2 == 0 && j % 2 != 0) ? 'black' : 'white';
fragment.appendChild(div);
}
}
board.appendChild(fragment);
};
#board {
background-color: #ccc;
height: 510px;
padding: 1px;
width: 510px;
}
.black,
.white {
float: left;
height: 100px;
margin: 1px;
width: 100px;
}
.black {
background-color: #333;
}
.white {
background-color: #efefef;
}
<div id="board"></div>
function crt_dv(){
dv=document.createElement('div'),document.body.appendChild(dv)
};
crt_dv(),dv.className='white';crt_dv(),dv.className='black';
Also use: for(i=0;i<2;i++)

Categories

Resources