How to insert object in div using JavaScript? - javascript

I am making Snake and Ladder game using JavaScript. I want to insert the game board generated from the create Board(dimension) function into a div, but [object Object] is what is appears.
var gameBoard = {
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'),
row = document.createElement('tr'),
cell = document.createElement('td'),
rowClone,
cellClone;
var output;
for (var r = 0; r < dimension; r++) {
rowClone = row.cloneNode(true);
table.appendChild(rowClone);
for (var c = 0; c < dimension; c++) {
cellClone = cell.cloneNode(true);
rowClone.appendChild(cellClone);
}
}
document.body.appendChild(table);
output = gameBoard.enumerateBoard(table);
}
return output;
},
enumerateBoard: function(board) {
var rows = board.getElementsByTagName('tr'),
text = document.createTextNode(''),
rowCounter = 1,
size = rows.length,
len,
cells,
real,
odd = false,
control = 0;
for (var r = size - 1; r >= 0; r--) {
cells = rows[r].getElementsByTagName('td');
len = cells.length;
rows[r].className = r % 2 == 0 ? 'even' : 'odd';
odd = ++control % 2 == 0 ? true : false;
size = rows.length;
for (var i = 0; i < len; i++) {
if (odd == true) {
real = --size + rowCounter - i;
} else {
real = rowCounter;
}
cells[i].className = i % 2 == 0 ? 'even' : 'odd';
cells[i].appendChild(text.cloneNode());
cells[i].firstChild.nodeValue = real;
rowCounter++;
}
}
return gameBoard;
}
};
//board.createBoard(10);
document.getElementById("div1").innerHTML = gameBoard.createBoard(10);
td {
border-radius: 10px;
width: 55px;
height: 55px;
line-height: 55px;
text-align: center;
border: 0px solid #FFFFFF;
}
table tr:nth-child(odd) td:nth-child(even),
table tr:nth-child(even) td:nth-child(odd) {
background-color: PowderBlue;
}
table tr:nth-child(even) td:nth-child(even),
table tr:nth-child(odd) td:nth-child(odd) {
background-color: SkyBlue;
}
td:hover {
background: LightCyan !important;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link href="StyleSheet1.css" rel="stylesheet" />
</head>
<body>
<div id="div1"></div>
<script src="JavaScript1.js"></script>
</body>
</html>
I need help on how to solve this problem. Thanks in advance.

All you wanted was the gameBoard to be appended to the div#div1, correct?
Added mount parameter to createBoard() function
var mount is a selector that will be referenced as the element to which the table element will be appended to.
Comments accompany changes in the code.
I added a border around #div1 to show that the gameBoard has been successfully appended to #div1
var gameBoard = { //===============▼---▼====[This is can be any selector]
createBoard: function(dimension, mount) {
//==▼------------------------------------▼====[Object mount]
var mount = document.querySelector(mount);
if (!dimension || isNaN(dimension) || !parseInt(dimension, 10)) {
return false;
} else {
dimension = typeof dimension === 'string' ? parseInt(dimension, 10) : dimension;
var table = document.createElement('table'),
row = document.createElement('tr'),
cell = document.createElement('td'),
rowClone,
cellClone;
var output;
for (var r = 0; r < dimension; r++) {
rowClone = row.cloneNode(true);
table.appendChild(rowClone);
for (var c = 0; c < dimension; c++) {
cellClone = cell.cloneNode(true);
rowClone.appendChild(cellClone);
}
}
//▼---------------------▼====[Object table append to Object mount]
mount.appendChild(table);
output = gameBoard.enumerateBoard(table);
}
return output;
},
enumerateBoard: function(board) {
var rows = board.getElementsByTagName('tr'),
text = document.createTextNode(''),
rowCounter = 1,
size = rows.length,
len,
cells,
real,
odd = false,
control = 0;
for (var r = size - 1; r >= 0; r--) {
cells = rows[r].getElementsByTagName('td');
len = cells.length;
rows[r].className = r % 2 == 0 ? 'even' : 'odd';
odd = ++control % 2 == 0 ? true : false;
size = rows.length;
for (var i = 0; i < len; i++) {
if (odd == true) {
real = --size + rowCounter - i;
} else {
real = rowCounter;
}
cells[i].className = i % 2 == 0 ? 'even' : 'odd';
cells[i].appendChild(text.cloneNode());
cells[i].firstChild.nodeValue = real;
rowCounter++;
}
}
return gameBoard;
}
};
/*board.createBoard(10);
[On window load call createBoard with 10 rows and mount it to #div1]
▼----------------------------▼===============================*/
window.onload = (function(e) {
gameBoard.createBoard(10, '#div1');
});
td {
border-radius: 10px;
width: 55px;
height: 55px;
line-height: 55px;
text-align: center;
border: 0px solid #FFFFFF;
}
table tr:nth-child(odd) td:nth-child(even),
table tr:nth-child(even) td:nth-child(odd) {
background-color: PowderBlue;
}
table tr:nth-child(even) td:nth-child(even),
table tr:nth-child(odd) td:nth-child(odd) {
background-color: SkyBlue;
}
td:hover {
background: LightCyan !important;
cursor: pointer;
}
#div1 {
border: 3px inset #0FF;
border-radius: 10px;
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="div1"></div>
</body>
</html>

Related

Multiplication Table in Javascript space between numbers?

var numbers = "";
for (var i = 1; i <= 13; i++){
for (var j = 1; j<= 13; j++){
numbers += (i*j) + '';
}
numbers += '<br>';
}
element.innerHTML = numbers;
how can i make a space between every number?
example:
You can use <table> for that to structure your text:
let numbers = "<tbody>";
for (let i = 1; i <= 13; i++){
numbers += '</tr>';
for (let j = 1; j<= 13; j++){
numbers += `<td>${i*j}</td>`;
}
numbers += '</tr>';
}
numbers += "</tbody>"
const element = document.querySelector("#element");
element.innerHTML = numbers;
td {
text-align: right;
width: 2em;
}
<table id="element">
You can use grid approach with some CSS variables to make cell elements, for more details see comments in Code snippet:
Also you could render headings of the cells.
const gridSize = 13;
// get grid element
const grid = document.querySelector('.grid');
// create temporary wrapper
const fragmentWrapper = document.createDocumentFragment();
const renderTop = () => {
for (var i = 0; i <= gridSize; i++) {
if (i === 0) {
// render mult char
renderCell('x');
continue;
}
renderCell(i, true);
}
}
const renderGrid = () => {
// append cells to wrapper
for (var i = 1; i <= gridSize; i++) {
for (var j = 0; j <= gridSize; j++) {
if (j === 0) {
// render heading cell
const num = i;
renderCell(num, true);
continue;
}
// render default cell
const num = i * j;
renderCell(num);
}
}
}
const renderCell = (num, select = false) => {
// create temporary cell
const cell = document.createElement('div');
cell.className = 'cell';
// if requested to highligh cell
select && cell.classList.add('select');
cell.innerText = `${ num }`;
// add cell to grid
fragmentWrapper.append(cell);
}
renderTop();
renderGrid();
// set grid size
grid.style.setProperty('--grid-size', gridSize);
// render grid
grid.append(fragmentWrapper);
.grid {
display: grid;
grid-template-columns: repeat(calc(var(--grid-size) + 1), 1fr);
/* using CSS grid size (set in JS) */
gap: .25rem;
}
.cell {
display: flex;
align-items: center;
/* align content */
justify-content: center;
/* align content */
aspect-ratio: 1/1;
/* make cell square */
border: 1px solid #d4d4d4;
/* show cell borders */
}
.cell.select {
background-color: tomato;
color: white;
font-weight: bold;
}
<div class="grid"></div>
You could be ambitious and, like David said, use CSS to take the weight of how the data is meant to be displayed. I've used CSS grid in this example which means you only need to have one loop, and the CSS takes care of the rest.
const arr = [];
const size = 13;
const limit = size * size;
// Push an HTML template string into
// the array
for (var i = 1; i <= limit; i++) {
arr.push(`<div>${i}</div>`);
}
// Add the joined array (it makes an HTML string
// to the element with the `grid` class
const grid = document.querySelector('.grid');
grid.innerHTML = arr.join('');
.grid {
display: grid;
grid-template-columns: repeat(13, 30px);
grid-gap: 0.2em;
}
.grid div {
border: 1px solid #cdcdcd;
font-size: 0.8em;
background-color: #efefef;
text-align: center;
padding: 0.5em 0;
}
<div class="grid"></div>
Additional documentation
Template/string literals
Edit: you can even create a function that will accept a number, and, using CSS variables, the function will work out the size of the grid required and return the HTML.
function createGrid(columns) {
const arr = [];
const grid = columns * columns;
document.documentElement.style.setProperty('--columns', columns)
// Push an HTML template string into
// the array
for (var i = 1; i <= grid; i++) {
arr.push(`<div>${i}</div>`);
}
return arr.join('');
}
const grid = document.querySelector('.grid');
grid.innerHTML = createGrid(5);
:root {
--columns: 13;
}
.grid {
display: grid;
grid-template-columns: repeat(var(--columns), 40px);
grid-gap: 0.2em;
}
.grid div {
border: 1px solid #cdcdcd;
font-size: 0.8em;
background-color: #efefef;
text-align: center;
padding: 0.5em 0;
}
<div class="grid"></div>
Please use like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: left;
padding: 8px;
}
</style>
</head>
<body>
<div id="test" style="width:800px;height: 350px; border: 1px solid sandybrown;">
</div>
<script>
var element = document.getElementById("test");
var html = "<table>";
for (var i = 1; i <= 10; i++){
html += "<tr>";
for (var j = 1; j<= 10; j++){
html += "<td>"+ (i*j) +"</td>";
}
html += '</tr> ';
}
html += "</table>";
element.innerHTML = html;
</script>
</body>
</html>

It is possible to create two table with js?

I am trying to create two tables and populate them with two randomized arrays. I don't remember how I got to this point but below is a codepen I have. I want to create a table class="side" and a table class="top" and put the random arrays in them. Please forgive me for the messy codes. I have no experience with coding and just want to make something for my students. Thank you.
edit1: cut the codes a little. I want to make a table with 3 cells in a column and another table with 4 cells in a row and randomly populate them with the two emojis array respectively. Can anyone help me with the JS codes?
<table class="top">
1
1
1
</table>
<table class="side">
2222
</table>
UPDATE:
Thanks to everyone for your input and advice. With the examples I was able to understand what my codes was lacking. I've posted it below for viewing and have hide the incomplete codes.
const animals = [
"🐕",
"🐈‍",
"🐄",
"🐐",
"🐎",
"🐖",
"🐇",
"🦆",
"🐔",
"🐁",
"🐑"
];
const fruits = [
"🍇",
"🍊",
"🍑",
"🥝",
"🍈",
"🍉",
"🥭",
"🍎",
"🍓",
"🍆",
"🥕",
"🥒",
"🫑",
"🧅",
"🍄"
];
function shuffle(a) {
let j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
shuffle(animals);
let t1side = document.getElementsByClassName("tside").item(0);
for (let x = 0; x < 3; x++) {
let tr = document.createElement("tr");
for (let y = 0; y < 1; y++) {
let td = document.createElement("td");
{
td.setAttribute("id", "r" + (x + 1) + "d" + (y + 1));
td.appendChild(document.createTextNode(animals[x * 1 + y]));
}
tr.appendChild(td);
}
t1side.appendChild(tr);
}
shuffle(fruits);
let t2top = document.getElementsByClassName("ttop").item(0);
for (let x = 0; x < 1; x++) {
let tr = document.createElement("tr");
for (let y = 0; y < 4; y++) {
let td = document.createElement("td");
{
td.setAttribute("id", "r" + (x + 1) + "d" + (y + 1));
td.appendChild(document.createTextNode(fruits[x * 1 + y]));
}
tr.appendChild(td);
}
t2top.appendChild(tr);
}
* {
padding: 0;
margin: 0;
}
.top {
top: 0px;
left: 200px;
position: absolute;
}
.side {
top: 100px;
left: 0px;
position: absolute;
}
table.ttop ,table.ttop tr,table.ttop td {
height: 50px;
width: 100px;
padding: 0px;
marging: 0px;
background-color: pink;
font-size: 50px;
text-align: center;
border-collapse: collapse;
border: 0px solid none;
}
table.tside, table.tside tr, table.tside td {
height: 50px;
width: 50px;
padding: 0px;
marging: 0px;
background-color: yellow;
font-size: 80px;
text-align: center;
border-collapse: collapse;
border: 0px solid none;
}
<body>
<style>
</style>
<body>
<div class="top">
<table class="ttop">
</table>
</div>
<div class="side">
<table class="tside">
</table>
</div>
</body>
<script>
</script>
</body>
var spaces2 = [
"🐕",
"🐇",
"🦆",
"🐔",
"🐁",
"🐑"
];
var spaces = [
"🍇",
"🍊",
"🍑",
"🥝",
"🍈",
"🍉",
"🥭",
"🍎",
];
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
shuffle(spaces2);
var tbody = document.getElementsByTagName("tbody").item(0);
for (var x = 0; x < 3; x++) {
var tr = document.createElement("tr");
for (var y = 0; y < 1; y++) {
var td = document.createElement("td");
{
td.setAttribute("id", "r" + (x + 1) + "d" + (y + 1));
td.appendChild(document.createTextNode(spaces2[x * 1 + y]));
}
tr.appendChild(td);
}
tbody.appendChild(tr);
}
shuffle(spaces);
var top = document.getElementsByClassName("top").item(0);
for (var x = 0; x < 1; x++) {
var tr = document.createElement("tr");
for (var y = 0; y < 4; y++) {
var td = document.createElement("td");
{
td.setAttribute("id", "r" + (x + 1) + "d" + (y + 1));
td.appendChild(document.createTextNode(spaces[x * 1 + y]));
}
tr.appendChild(td);
}
tbody.appendChild(tr);
}
* {
padding: 0;
margin: 0;
}
table.top tbody, tr, td {
height: 50px;
width: 50px;
padding: 0px;
marging: 0px;
background-color: none;
font-size: 40px;
text-align: center;
border-collapse: collapse;
border: 0px solid none;
}
table.side tbody, tr, td {
height: 50px;
width: 50px;
padding: 0px;
marging: 0px;
background-color: none;
font-size: 40px;
text-align: center;
border-collapse: collapse;
border: 0px solid none;
}
<body>
<style>
</style>
<body>
<div class="top">
<table id="top">
</table>
<div class="side">
<table id="side">
<tbody></tbody>
</table>
</div>
</body>
<script>
</script>
</body>
You want to generate tables from javaScript using an aYrray as content. Here is a small snippet of the generation of a table.
const spaces = [
"🍇",
"🍊",
"🍑",
"🥝",
"🍈",
"🍉",
"🥭",
"🍎",
"🍓",
"🍆",
"🥕",
"🥒",
"🫑",
"🧅",
"🍄"
];
function loadEvents() {
generateTable(spaces, "container", ["class1", "class2", "class3", "etc"]);
}
function generateTable(dataTable, containerId, classes) {
shuffle(dataTable);
let container = document.getElementById(containerId);
let table = document.createElement("table");
// Add classes to table
for (const clazz of classes) {
table.classList.add(clazz);
}
// Calculate cant of rows and columns
let cantDataRow = 0;
let cantDataCol = 0;
do {
cantDataRow++;
cantDataCol = Math.ceil(dataTable.length / cantDataRow);
} while (dataTable.length / Math.pow(cantDataRow, 2) > 1);
let aux = 0;
for (let i = 0; i < cantDataRow; i++) { // rows
let row = document.createElement("tr");
for (let j = 0; j < cantDataCol; j++) { // columns
let col = document.createElement("td");
col.textContent = dataTable[aux++];
row.appendChild(col); // Add column to row
}
table.appendChild(row); // Add row to table
}
container.appendChild(table); // Add table to container
}
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
addEventListener("DOMContentLoaded", loadEvents);
table, tr, td{
border: 1px solid black;
border-collapse: collapse;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div id="container"></div>
<script src="script.js"></script>
</body>
</html>
You would only have to call the function passing it the array with the data of the table, the container of the table and the classes that you want it to contain.
It is not necessary to create the shuffle function twice. It is created only once and can be called infinitely many times. I recommend using let instead of var.
Nice question :-) You only need one loop for each table. I did it with a for loop. I added a function that outputs a random image.
const t1 = document.querySelector('.top');
const t2 = document.querySelector('.side');
const spaces2 = [
"🐕",
"🐇",
"🦆",
"🐔",
"🐁",
"🐑"
];
const spaces = [
"🍇",
"🍊",
"🍑",
"🥝",
"🍈",
"🍉",
"🥭",
"🍎",
];
let tr = document.createElement('tr');
for (let i = 0; i < 3; i++) {
let td = document.createElement('td');
td.innerHTML = getRandomElement(spaces2);
tr.append(td);
}
t1.append(tr);
// t2
for (let i = 0; i < 4; i++) {
let tr = document.createElement('tr');
let td = document.createElement('td');
td.innerHTML = getRandomElement(spaces);
tr.append(td);
t2.append(tr);
}
function getRandomElement(items) {
return items[Math.floor(Math.random()*items.length)];
}
small {
font-size: 16px;
padding-left:5px;
}
table {
}
table td {
border: 2px solid #999;
padding: 5px;
}
<h2>Table 1<small>3 cols and 1 row</small></h2>
<table class="top"></table>
<h2>Table 2<small>1 cols with 4 rows</small></h2>
<table class="side"></table>

Why with "array[row][col]= usedspace;" cannot increase specific columns and rows depending on the increse each variable (row or column)?

I am Michael and I am new to this forum.
What I want to ask is how through Java Script to make a character 'O' follow your character 'X' in a '.' that is a 20*20 array, but where 'X' pass '.' is replaced with 'O'.
E.g. increase some way the counters inside the if statement that relies in the for loops of row and column of "array a" ?
function start()
{
document.getElementById("wrapper").style="visibility:hidden";
var optionOne = document.getElementById("optionOne");
var display = "";
var txt1 = document.getElementById("txt1");
var mtxt1 = parseInt(txt1.value);
if (mtxt1 == 1)
{
display += "<p>Pen is currently NOT DRAWING</p>";
document.getElementById("wrapper").style="visibility:display";
}
else if (mtxt1 == 2)
{
display += "<p>Pen is DRAWING</p>";
document.getElementById("wrapper").style="visibility:display";
}
optionOne.innerHTML = display;
var button = document.getElementById("getbutton");
button.addEventListener("click",start,false );
//var displaygmb = document.getElementById("displaygmb");
//displaygmb.addEventListener("click", displaygameboard("Gameboard",array,length,arraydisplay),false );
var button2 = document.getElementById("get2button");
button2.addEventListener("click",option2(button2,mtxt1),false );
}
function option2(buttonn,symbolinput)
{
var input = symbolinput;
var usedspace = "O";
var turtle = "X";
var gameboardSymbol = ".";
var clickcountt = buttonn;
var count6 = 1;
var count5 = 1;
var count3 = 1;
var count4 = 1;
var display = "";
clickcountt.onclick = function() {
var optiontwo = document.getElementById("optiontwo");
var display2 = "";
var txt2 = document.getElementById("txt2");
var mtxt2 = parseInt(txt2.value);
if (mtxt2 == 6)
{
count6 += 1;
display2 += "<p>Turtle is moving "+count6+" places down</p>";
}
else if (mtxt2 == 5)
{
count6 -=1;
count5 +=1;
display2 += "<p>Turtle is moving "+count6+" places up</p>";
}
else if (mtxt2 == 3)
{
count3 += 1;
display2 += "<p>Turtle is moving "+count3+" places to the right</p>";
}
else if (mtxt2 == 4)
{
count3 -=1
count4 += 1;
display2 += "<p>Turtle is moving "+count3+" places to the left</p>";
}
optiontwo.innerHTML = display2;
var gameboardsize = 20;
var arraydisplay = document.getElementById("arraydisplay");
var array = new Array (gameboardsize);
var length = array.length;
for (var i = 0; i <= length; i++ )
{
array[i] = new Array(gameboardsize);
}
var arraydisplay = document.getElementById("arraydisplay");
var displaygbd = "<table id=gameb align=center><thead><th>"+"Gameboard"+"</th></thead><tbody>";
for (var row = 1; row <= length; row++)
{
//three += 1;
displaygbd += "<tr>";
for (var col = 1; col <= length; col++)
{
if (input == 1){
//four += 1;
if (((row ==count6)&&(col ==count3)))
{
array[row][col]= turtle;
}
else {
array[row][col]=gameboardSymbol;
}
}
//----------------------------
else if(input == 2)
{
if (((row == count6)&&(col ==count3)))
{
array[row][col]= turtle;
}
/*how to make 'O' follow 'X' by ibncrease the appropriate counter in the if below?*/
else if (((row <= count6)&&(col <=count3)))
{
array[row][col]= usedspace;
}
else if ((((row >= count6)||(col >= count3))))
{
array[row][col]=gameboardSymbol;
}
}//end else if
//----------------------------
displaygbd += "<th>"+array[row][col]+"\xa0"+"</th>";
}
displaygbd += "</tr>";
}
displaygbd += "</tbody></table>";
arraydisplay.innerHTML = displaygbd;
}//end clickout function
}
window.addEventListener("load",start,false);
#charset "ISO-8859-1";
#customers {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 30%;
}
#customers td, #customers th {
border: 1px solid #ddd;
padding: 8px;
}
#customers thead th {
padding-top: 12px;
padding-bottom: 12px;
text-align: center;
background-color: #4CAF50;
color: white;
}
#customers tbody th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: white;
color: black;
text-align:center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Initializing an array</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src ="tutle.js"></script>
</head>
<body>
select your first option
<input id ="txt1" type="text">
<input id = "getbutton" type ="button" value = "your option">
<div id = "optionOne"></div>
<br/>
<div id = "arraydisplay"></div>
<div id="wrapper" >
select your second option
<input id ="txt2" type="text">
<input id = "get2button" type ="button" value = "your option">
<div id = "optiontwo"></div>
</div>
<div id = "counters"></div>
<div id = "optionthree"></div>
</body>
</html>
Sharing a possible solution.
This should get you more than started.
Try running this here itself and let me know if this is ok. I'll add an explanation if required.
The 2 inputs receive the new location of 'X'. text1 receives row number and text2 receives column number. On button press, the corresponding dimension is updated.
var button1 = document.getElementById('getbutton');
var button2 = document.getElementById('get2button');
var textbox1 = document.getElementById('txt1');
var textbox2 = document.getElementById('txt2');
var gridX = 20;//table size length wise
var gridY = 20;//table size width wise
var arrayContainer = document.getElementById('arraydisplay');
var currentX = 1;//initial positions
var currentY = 1;
function init() {
var myTable = document.createElement('table');
myTable.setAttribute("id", "customers");
arrayContainer.appendChild(myTable);
//Creating initial grid
for(var i=0; i<gridX; i++) {
var row = document.createElement('tr');
for(var j=0; j<gridY; j++) {
var text = document.createTextNode('.');
var column = document.createElement('td');
column.appendChild(text);
row.appendChild(column);
}
myTable.appendChild(row);
}
//Setting initial value
document.getElementsByTagName('tr')[currentX-1].getElementsByTagName('td')[currentY-1].innerText = 'X';
}
init();
button1.onclick = clicked;
function clicked() {//1st position changed
var newX = parseInt(textbox1.value);
var newY = parseInt(textbox2.value);
moveTo(newX, newY);
}
button2.onclick = clicked;
function moveTo(newX, newY) {
//Setting old value to 'O'
var char = 'O'
if(newX == 1)
char = '.';
document.getElementsByTagName('tr')[currentX-1].getElementsByTagName('td')[currentY-1].innerText = char;
//Setting new location with 'X'
document.getElementsByTagName('tr')[newX-1].getElementsByTagName('td')[newY-1].innerText = 'X';
//Updating current location of 'X' for future use.
currentX = newX;
currentY = newY;
}
#charset "ISO-8859-1";
#customers {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 30%;
}
#customers td, #customers th {
border: 1px solid #ddd;
padding: 8px;
}
#customers thead th {
padding-top: 12px;
padding-bottom: 12px;
text-align: center;
background-color: #4CAF50;
color: white;
}
#customers tbody th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: white;
color: black;
text-align:center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Initializing an array</title>
<link rel="stylesheet" type="text/css" href="style.css">
<!-- <script src ="turtle.js"></script> -->
</head>
<body>
select your first option
<input id ="txt1" type="text">
<input id = "getbutton" type ="button" value = "your option">
<div id = "optionOne"></div>
<div id="wrapper" >
select your second option
<input id ="txt2" type="text">
<input id = "get2button" type ="button" value = "your option">
<div id = "optiontwo"></div>
</div>
<div id = "counters"></div>
<div id = "optionthree"></div>
<br>
<div id = "arraydisplay"></div>
</body>
<script src ="turtle.js"></script>
</html>

Updating HTML element's content during script execution in vanilla JS

I'm writing simple Sudoku solver as an exercise and I've thought that I will show entire process by displaying it step by step on 9x9 grid.
I'm using HTML table with nested divs for displaying game board (probably not relevant) and recursive function for solving preseeded Sudoku. My solution is in "spaghetti" state right now, so below I give you pseudocode for what I have:
function fillBoard() {
for(let i = 0; i < 9; i++) {
for(let j = 0; j < 9; j++) {
const cell = document.querySelector(`div[data-row="${i}"][data-column="${j}"]`);
cell.innerHTML = gameState.solution[i][j];
}
}
}
function solve(row, column) {
/* simplified, it's working :) */
for(let guess = 1; guess < 10; guess++) {
this.solution[row][column] = guess; <--- SHOW THIS STEP TO USER
let conflicts = checkConflicts(row, column)
if(!conflicts) {
let emptyCell = this.findNextEmptyCell(row, column);
if(emptyCell) {
let result = this.solve(emptyCell.i, emptyCell.j);
if(!result) continue;
else return true;
}
return true;
}
else continue;
}
}
I've tried putting fillBoard() function call inside solve() but that obviously didn't worked as I'm getting only the final result in form of solved grid. I've also tried using setInterval(fillBoard, 100) but solve() function is executing too fast.
How can I achieve "incremental" displaying of entire solving process by updating HTML after each solve() call?
I'm trying to get something like this: https://www.youtube.com/watch?v=ChjQRIhH414 but I'm filling the board left-right, top-bottom
Current solution: Codepen
You'll want to slow down your html rendering process, which suggests animation to me. You can look into this approach, and maybe throttle it if you want. Without having a complete example I can't run it to be sure. I'll give you some pseudo code in response for the way I would test it to start with, and hopefully that'll point you in the right direction:
function fillBoard(i=0, j=0) {
const cell = document.querySelector(`div[data-row="${i}"][data-column="${j}"]`);
cell.innerHTML = gameState.solution[i][j];
j++;
if( j >= 9) { j = 0; i++; }
if(i < 9)
requestAnimationFrame(function() { fillBoard(i,j) });
}
If you want, you can replace requestAnimationFrame with a setTimeout on a given delay. You can set it to 1-2 seconds or something to start with to see if it gives you the results you're looking for.
Unoptimized, but working example, by following #loctrice advice from comments above. Still looking for other solutions to this problem.
console.clear();
let states = [];
let x = 0;
document.addEventListener("DOMContentLoaded", function() {
const start = document.getElementById("start");
const check = document.getElementById("check");
const sudoku = document.getElementById("sudoku");
function fillBoard(index) {
console.log(`Displaying ${index}/${states.length}`);
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const cell = document.querySelector(
`div[data-row="${i}"][data-column="${j}"]`
);
cell.innerHTML =
states[index][i][j] == 0 ? "" : states[index][i][j];
}
}
}
class Sudoku {
checkRow(row) {
for (let i = 0; i < 9; i++) {
let number = this.solution[row][i];
if (!number) continue;
for (let j = 0; j < 9; j++) {
if (i == j) continue;
const challenge = this.solution[row][j];
if (number == challenge) return number;
}
}
return false;
}
checkColumn(column) {
for (let i = 0; i < 9; i++) {
let number = this.solution[i][column];
if (!number) continue;
for (let j = 0; j < 9; j++) {
if (i == j) continue;
const challenge = this.solution[j][column];
if (number == challenge) return number;
}
}
return false;
}
checkBox(box) {
const rowModifier = Math.floor(box / 3) * 3;
const colModifier = (box % 3) * 3;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let number = this.solution[i + rowModifier][j + colModifier];
if (!number) continue;
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
if (x == i && y == j) continue;
const challenge = this.solution[x + rowModifier][y + colModifier];
if (number == challenge) return number;
}
}
}
}
return false;
}
solve(row, column, array) {
for (let guess = 1; guess < 11; guess++) {
if (guess == 10) {
this.solution[row][column] = 0;
return false;
}
this.solution[row][column] = guess; // <=== SHOW ENTIRE BOARD HERE
let state = this.solution.map(a => [...a]);
array.push(state);
const rowError = this.checkRow(row);
const columnError = this.checkColumn(column);
const boxError = this.checkBox(
3 * Math.floor(row / 3) + Math.floor(column / 3)
);
if (!rowError && !columnError && !boxError) {
// find next empty cell
let emptyCell = this.findNextEmptyCell(row, column);
if (emptyCell) {
let result = this.solve(emptyCell.i, emptyCell.j, array);
if (!result) continue;
else return true;
}
return true;
} else continue;
}
}
findNextEmptyCell(row, column) {
for (let i = row; i < 9; i++) {
if (column == 8) column = 0;
for (let j = column; j < 9; j++) {
if (this.solution[i][j]) continue;
else return { i: i, j: j };
}
column = 0;
}
return false;
}
generateBox(boxNumber) {
let numbers = [];
for (let i = 0; i < 9; i++) {
numbers.push(i);
}
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const length = numbers.length;
const index = Math.floor(Math.random() * length);
const number = numbers.splice(index, 1);
const row = i + boxNumber * 3 / 4;
const col = j + boxNumber * 3 / 4;
this.solution[row][col] = parseInt(number) + 1;
}
}
}
initialize() {
this.solution = [];
for (let i = 0; i < 9; i++) {
this.solution.push([]);
for (let j = 0; j < 9; j++) {
this.solution[i][j] = 0;
}
}
for (let i = 0; i < 3; i++) {
this.generateBox(i * 4);
}
}
}
let gameState = new Sudoku();
gameState.initialize();
start.onclick = function() {
gameState.solve(0, 3, states);
window.setInterval(function() {if(x < states.length) fillBoard(x++);}, 15);
};
check.onclick = function() {
for (let i = 0; i < 9; i++) {
let error = gameState.checkRow(i);
if (error) {
for (let j = 0; j < 9; j++) {
const cell = document.querySelector(
`div[data-row="${i}"][data-column="${j}"]`
);
cell.classList.add("incorrect-area");
if (cell.innerHTML == error) cell.classList.add("incorrect");
}
return;
}
error = gameState.checkColumn(i);
if (error) {
const cells = document.querySelectorAll(`div[data-column="${i}"]`);
cells.forEach(c => {
c.classList.add("incorrect-area");
if (c.innerHTML == error) c.classList.add("incorrect");
});
return;
}
error = gameState.checkBox(i);
if (error) {
const cells = document.querySelectorAll(`div[data-box="${i}"]`);
cells.forEach(c => {
c.classList.add("incorrect-area");
if (c.innerHTML == error) c.classList.add("incorrect");
});
return;
}
}
};
for (let i = 0; i < 9; i++) {
const row = document.createElement("tr");
row.classList.add("row");
for (let j = 0; j < 9; j++) {
let td = document.createElement("td");
let cell = document.createElement("div");
cell.classList.add("cell");
cell.dataset.row = i;
cell.dataset.column = j;
let a = Math.floor(i / 3);
let b = Math.floor(j / 3);
cell.dataset.box = 3 * a + b;
cell.innerHTML =
gameState.solution[i][j] == "0" ? "" : gameState.solution[i][j];
if (!cell.innerHTML)
cell.onclick = function(e) {
const row = e.target.dataset.row;
const col = e.target.dataset.column;
gameState.solution[row][col] =
++gameState.solution[row][col] > 9
? 0
: gameState.solution[row][col];
cell.innerHTML =
gameState.solution[row][col] == "0"
? ""
: gameState.solution[row][col];
document
.querySelectorAll("div.cell")
.forEach(c =>
c.classList.remove("correct", "incorrect", "incorrect-area")
);
};
td.appendChild(cell);
row.appendChild(td);
}
sudoku.appendChild(row);
}
});
.incorrect-area {
background-color: #A55 !important;
border-color: #F00 !important;
}
.correct {
background-color: #1A1 !important;
border-color: #0F0 !important;
}
.incorrect {
background-color: #A11 !important;
border-color: #F00 !important;
}
div[data-box='1'],
div[data-box='3'],
div[data-box='5'],
div[data-box='7'] {
background-color: #444;
}
.button {
display: inline-block;
min-height: 30px;
width: 120px;
background-color: white;
font-size: 32px;
cursor: pointer;
}
#buttons {
text-align: center;
}
div {
padding: 0px;
}
body {
background-color: #000;
}
#game {
width: 500px;
margin-left: auto;
margin-right: auto;
margin-top: 0px;
}
#sudoku {
width: 500px;
height: 500px;
margin-left: auto;
margin-right: auto;
background-color: #111;
border: dashed 1px white;
color: white;
}
.row {
border: 1px solid yellow;
}
.cell {
cursor: default;
height: 40px;
width: 40px;
padding: 0;
margin: 0;
border: solid white 1px;
text-align: center;
font-weight: bold;
display: table-cell;
vertical-align: middle;
user-select: none;
}
.cell:hover {
background-color: #765;
transform: scale(1.3);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>SudoQ</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="main.js"></script>
</head>
<body>
<div id="game">
<div id="buttons">
<div id="start" class="button">SOLVE</div>
<div id="check" class="button">CHECK</div>
</div>
<table id="sudoku">
</table>
</div>
</body>
</html>

How to create diagonal of table using jquery

I would like to create diagonal in my table. For example if i have table 5x5 i have to grab first row and first column in this row and set background of thic column to be red. For the second row i have to do the same on second column in second row.
var cols = 6,
rows = 6;
for (r = 0; r < rows; r++) {
var row = $('<tr></tr>')
$('table').append(row);
for (c = 0; c < cols; c++) {
var col = $('<td></td>');
row.append(col);
$(col[r][c]).addClass('kolorek')
}
}
table td {
width: 20px;
height: 20px;
border: 1px solid;
}
.kolorek {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
</table>
Here is a fiddle
You're almost there.
var cols = 6,
rows = 6,
$table = $('table'); // Caching the table, because this will be called many times (perf improvement)
for (r = 0; r < rows; r++) {
var row = $('<tr></tr>')
for(c = 0; c < cols; c++){
var col = $('<td></td>')
if(c==r) col.addClass('kolorek') // col[r][c] is undefined. This matches the same column and row numbers
row.append(col)
}
$table.append(row);
}
table td {
width: 20px;
height: 20px;
border: 1px solid;
}
.kolorek {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table></table>
You can just check if the row index equals the column index to make a diagonal line from left top to right bottom:
var cols = 6,
rows = 6;
for (r = 0; r < rows; r++) {
var row = $('<tr></tr>')
$('table').append(row);
for (c = 0; c < cols; c++) {
var col = $('<td></td>');
row.append(col);
if (r == c) col.addClass('kolorek'); // add this in place of your current kolerik adder
}
}
table td {
width: 20px;
height: 20px;
border: 1px solid;
}
.kolorek {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
</table>

Categories