My homework was to create a scipt that connects two marked cells of a table. My solution works fine, but the result line is a bit disproportionate.
As you can see, the last row is 4-cells long while all other rows are 3-cells long. But I'd like the middle part of a line to be the longest. Like this:
How to get the desired result and not make the code too complicated. The code itself:
function connectThem() {
if (markedCells.length == 2) {
y_distance = markedCells[0][0] - markedCells[1][0];
y_distance = Math.abs(y_distance) + 1; // vertial distance
x_distance = markedCells[0][1] - markedCells[1][1];
x_distance = Math.abs(x_distance) + 1; // horizontal distance
if (x_distance > y_distance) { // if horizontal distance greater than vertical distance
x_distance -= 0;
alert("horizontal connection");
totalRows = y_distance;
for (var row = 0; row < y_distance; row++) {
thisRowLength = Math.floor(x_distance / totalRows);
for (var c = 0; c < thisRowLength; c++) {
document.getElementById('cell-' + markedCells[0][0] + '-' + markedCells[0][1]).style.backgroundColor = "red";
markedCells[0][1] = parseInt(markedCells[0][1]) + 1;
}
markedCells[0][0] = parseInt(markedCells[0][0]) + 1;
totalRows -= 1; // vertical remaining
x_distance -= thisRowLength; // horizontal remaining
}
} else {
y_distance -= 0;
alert("vertical or horizontal connection");
totalCols = x_distance;
for (var col = 0; col < x_distance; col++) {
thisColLength = Math.floor(y_distance / totalCols);
for (var r = 0; r < thisColLength; r++) {
document.getElementById('cell-' + markedCells[0][0] + '-' + markedCells[0][1]).style.backgroundColor = "red";
markedCells[0][0] = parseInt(markedCells[0][0]) + 1;
}
markedCells[0][1] = parseInt(markedCells[0][1]) + 1;
totalCols -= 1;
y_distance -= thisColLength;
}
}
alert("x distance: " + x_distance + " y distance: " + y_distance);
} else {
alert("Can't connect " + markedCells.length + " cells together :-(")
}
}
var htmlElements = ""; // storing the whole table here
for (var r = 1; r < 41; r++) { // creating the table row by row
htmlElements += '<tr>';
for (var c = 1; c < 61; c++) { // and column by column
htmlElements += '<td class="tCell white" id="cell-' + r.toString() + '-' + c.toString() + '"></td>';
}
htmlElements += '</tr>'
}
var theTable = document.getElementById("tab");
theTable.innerHTML = htmlElements;
var allTableCells = document.querySelectorAll("td"); // adding all cells to an array
var markedCells = [] // storing marked cells here
for (var i = 0; i < allTableCells.length; i++) {
allTableCells[i].addEventListener("click", function() { // when click any cell
let stringID = this.id.split('-');
if (this.className == "tCell white") {
this.className = "tCell red";
markedCells.push([stringID[1], stringID[2]]);
} else {
this.className = "tCell white";
let index = markedCells.indexOf([stringID[1], stringID[2]]);
markedCells.splice(index, 1);
}
console.log(markedCells);
});
}
body {
background-color: #333;
}
#workspace {
position: absolute;
width: 900px;
height: 600px;
background-color: whitesmoke;
top: 50%;
left: 50%;
margin-left: -450px;
margin-top: -300px;
}
table,
tr,
td {
border: 1px solid black;
border-collapse: collapse;
padding: 0;
}
table {
width: 900px;
height: 600px;
}
.red {
background: red;
color: white;
}
.white {
background: white;
color: black;
}
#btn {
position: absolute;
width: 100px;
top: 50px;
left: 50%;
margin-left: -50px;
}
<div id="workspace">
<table id="tab">
</table>
</div>
<button id="btn" onclick="connectThem()">Connect!</button>
Related
I am just creating a table and I have 2 images on this table.I have 1 image in one box ,color black and 1 image on a box that it is red.I take the images with css. I want to have in the one box that I have the black ,another 14 images,so in one box I will have 15 images.If you see (1,1) there located the black image.In that position I want another 14 images of blacks.I didn't know how to do that .This code is for to create my table and those pictures inside.
let colors={black:"https://i.imgur.com/dL3J8XS.jpeg",red:'https://i.imgur.com/ZEZLSOo.png'}
//
let items = [
{
"x": 1,
"y": 1,
"piece":"p",
"piece_color": "black",
"b_color": "black"
},
{
"x": 12,
"y": 2,
"piece":"p",
"piece_color": "red",
"b_color": "red"
}
];
$(function () {
draw_empty_board();
fill_board();
//$('#do_move').click(do_move);
//$('#chess_reset').click(do_reset);
});
function draw_empty_board() {
var t='<table id="chess_table">';
for(var i=2;i>0;i--) {
t += '<tr>';
t += '<td class="line_label">'+i+'</td>';
for(var j=1;j<13;j++) {
t += '<td class="chess_square" id="square_'+j+'_'+i+'"></td>';
}
t+='</tr>';
}
t += '<tr><td class="column_label line_label"></td>';
for(var j=1;j<13;j++) {
t += '<td class="column_label">'+j+'</td>';
}
t+='</tr>';
t+='</table>';
$('#chess_board').html(t);
}
function fill_board() {
//$.ajax({url: "chess.php/board/", success: fill_board_by_data });
//I'm a calling static data here
fill_board_by_data(items);
}
function fill_board_by_data(data) {
for(var i=0;i<data.length;i++) {
var o = data[i];
var id = '#square_'+ o.x +'_' + o.y;
//var c = (o.piece!=null)?o.piece_color + o.piece:'';
var c = (o.piece!=null)?o.piece_color:'';
//$(id).append('<span class="'+c+'dot"></span>');
var im = (o.piece!=null)?'<img class="piece" src="'+colors[c]+'.png">':'';
$(id).addClass(o.b_color+'_square').html(im);
}
}
the css code is this
table{
border-collapse:collapse;
border:2px solid;
}
td{
width:25px;
height:25px;
border:1px solid;
}
/*this is a suggested Css alternative to images */
.reddot {
height: 25px;
width: 25px;
background-color: red;
border-radius: 50%;
display: inline-block;
}
.blackdot {
height: 25px;
width: 25px;
background-color: #000;
border-radius: 50%;
display: inline-block;
}
img{width:25px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chess_board"></div>
You can check if o.piece_color is red or black depending on this assign total images you need to add inside td .Then , just use for-loop this will run until count inside this loop append images to some variable using += and finally append this to your required td.
Demo Code :
let colors = {
black: "https://i.imgur.com/dL3J8XS.jpeg",
red: 'https://i.imgur.com/ZEZLSOo.png'
}
//
let items = [{
"x": 1,
"y": 1,
"piece": "p",
"piece_color": "black",
"b_color": "black"
},
{
"x": 12,
"y": 2,
"piece": "p",
"piece_color": "red",
"b_color": "red"
}
];
$(function() {
draw_empty_board();
fill_board();
});
function draw_empty_board() {
var t = '<table id="chess_table">';
for (var i = 2; i > 0; i--) {
t += '<tr>';
t += '<td class="line_label">' + i + '</td>';
for (var j = 1; j < 13; j++) {
t += '<td class="chess_square" id="square_' + j + '_' + i + '"></td>';
}
t += '</tr>';
}
t += '<tr><td class="column_label line_label"></td>';
for (var j = 1; j < 13; j++) {
t += '<td class="column_label">' + j + '</td>';
}
t += '</tr>';
t += '</table>';
$('#chess_board').html(t);
}
function fill_board() {
fill_board_by_data(items);
}
function fill_board_by_data(data) {
for (var i = 0; i < data.length; i++) {
var o = data[i];
var id = '#square_' + o.x + '_' + o.y;
var c = (o.piece != null) ? o.piece_color : '';
var im = (o.piece != null) ? '<img class="piece" src="' + colors[c] + '.png">' : '';
var htmls = ''; //delcare this
//check color if black 14 or 15(red)
var count = (o.piece_color == "black") && (o.piece != null) ? 14 : 15
//loop till count
for (var j = 0; j < count; j++) {
//append img
htmls += '<img class="piece" src="' + colors[c] + '.png">';
}
//finally add img inside td
$(id).addClass(o.b_color + '_square').html(htmls)
}
}
table {
border-collapse: collapse;
border: 2px solid;
}
td {
width: 25px;
height: 25px;
border: 1px solid;
}
/*this is a suggested Css alternative to images */
.reddot {
height: 25px;
width: 25px;
background-color: red;
border-radius: 50%;
display: inline-block;
}
.blackdot {
height: 25px;
width: 25px;
background-color: #000;
border-radius: 50%;
display: inline-block;
}
img {
width: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chess_board"></div>
Run the Code Snippet Please, it'll allow you to understand my question better
As you can see, I have cells with numbers and one Cell with Symbol (S) and red color.
If i click on any other cells, my (S)"UniqueCell" will move there.
lets say I click on Cell with number 55, My UniqueCell will move there, replacing the 55 with (S), now I click on other cell, lets say cell that have number 320, my UniqueCell moves from cell 55 to cell 320, now my UniqueCell replaced the 320, with it's (S), however cell 55 gained back its numbers.
How i can prevent the cells from gaining back its numbers? how i can make it lose its numbers permanently once i clicked on it?
note: I'm trying to make a game where player A pick vertical and player B to pick horizontal, hence the green moving vertical and horizontal every click, if possible, i want each time i click on cell where the green is, if it was Vertical, player gain those points, if it was horizontal, player b gain the points
var isCol = 0;
var board = [];
for (r = 0; r < 7; r++) {
var line = [];
for (c = 0; c < 7; c++) {
line.push(RandomGenerator(50, 500));
}
board.push(line);
}
function prs(curr, c, r) {
showTable(curr, c, r);
isCol = (isCol + 1) % 2;
}
function toColor(col, row, chosen_col, chosen_row) {
var ret = false;
switch (isCol) {
case 0:
if (row == chosen_row) {
ret = true;
}
break;
case 1:
if (col == chosen_col) {
ret = true;
}
break;
}
return ret;
}
function showTable(c, chosen_col, chosen_row) {
var str = "";
str += "<table border=1>";
for (row = 0; row < 7; row++) {
str += "<tr>";
for (let col = 0; col < 7; col++) {
str += "<td onclick='prs(this, " + col + "," + row + ")'";
if (toColor(col, row, chosen_col, chosen_row)) {
if(c.textContent == board[row][col]){
str += " class=uniqueCell";
}
else str += " class='grn' ";
}
str += ">";
if(c.textContent == board[row][col]){
str += 'S';
}
else str += board[row][col];
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
document.getElementById("ff").innerHTML = str;
}
function RandomGenerator(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
showTable(-1);
var getUnique = function(){
var tdElements = document.querySelectorAll('#ff td');
tdElements[
RandomGenerator(0, tdElements.length)
].classList.add('uniqueCell');
// update the text of the cell using the class
document.querySelector('.uniqueCell').textContent = 'S';
};
getUnique();
td{
border:2px solid black;
width:10px;
height:10px;
text-align: center;
}
td:hover{background-color:lightgreen;}
.grn{
background-color:green;
color:white;
}
.uniqueCell {
background-color: tomato;
}
<div id="ff"></div>
we keep points collected in object P1 & P2 it has for now points property P1.points & P2.points
I added inside prs() funtion called in Onclick
$('#turn').text(`Player ${(isCol+1)} turn`);
if (CellPoint) {
if (isCol) {P1.points+=CellPoint;}else{P2.points+= CellPoint;}
$('#p1').text(`Player 1: ${P1.points}`);
$('#p2').text(`Player 2: ${P2.points}`);
} else {
console.log('selected S');
}
var isCol = 0;
var CellPoint = 0;
var board = [];
var P1 = {
points: 0
};
var P2 = {
points: 0
};
for (r = 0; r < 7; r++) {
var line = [];
for (c = 0; c < 7; c++) {
line.push(RandomGenerator(50, 500));
}
board.push(line);
}
function prs(curr, c, r) {
CellPoint = parseInt($(curr).text());
showTable(curr, c, r);
isCol = (isCol + 1) % 2;
clr = isCol ? 'blue' : 'red';
$(curr).text('S');
$('#turn').css("color", clr)
.text(`Player ${(isCol+1)} turn`);
if (CellPoint) {
if (isCol) {
P1.points += CellPoint;
} else {
P2.points += CellPoint;
}
$('#p1').text(`Player 1: ${P1.points}`);
$('#p2').text(`Player 2: ${P2.points}`);
} else {
console.log('selected S');
}
}
function toColor(col, row, chosen_col, chosen_row) {
var ret = false;
switch (isCol) {
case 0:
if (row == chosen_row) {
ret = true;
}
break;
case 1:
if (col == chosen_col) {
ret = true;
}
break;
}
return ret;
}
function showTable(c, chosen_col, chosen_row) {
if(c!==-1){board[chosen_row][chosen_col] = 'S';}
var str = "";
str += "<table border=1>";
for (row = 0; row < 7; row++) {
str += "<tr>";
for (let col = 0; col < 7; col++) {
str += "<td onclick='prs(this, " + col + "," + row + ")'";
if(board[row][col]=='S'){
str += " class=uniqueCell";
} else{
if (toColor(col, row, chosen_col, chosen_row)) {
str += " class='grn' ";} }
str += ">";
if(board[row][col]=='S') {
str += 'S';
} else str += board[row][col];
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
document.getElementById("ff").innerHTML = str;
}
function RandomGenerator(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
showTable(-1);
var getUnique = function() {
var tdElements = document.querySelectorAll('#ff td');
tdElements[
RandomGenerator(0, tdElements.length)
].classList.add('uniqueCell');
// update the text of the cell using the class
document.querySelector('.uniqueCell').textContent = 'S';
};
getUnique();
td {
border: 2px solid black;
width: 10px;
height: 10px;
text-align: center;
}
td:hover {
background-color: lightgreen;
}
.grn {
background-color: green;
color: white;
}
.turn1 {
background-color: green;
color: red;
}
.turn0 {
background-color: green;
color: blue;
}
.uniqueCell {
background-color: tomato;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><span id='p1' style='color:red;'>Player1: </span> X <span style='color:blue;' id='p2'>Player2: </span></div>
<p id='turn'>Player 1 turn</p>
<div id="ff"></div>
The issue is you are redrawing the table in each click of cells, as a result keeping track of the previously clicked elements are little bit difficult. Instead create the table only for single (first) time then loop through all the td's to add the style and text based on specific condition.
You can try the following way:
var isCol = 0;
var board = [];
for (r = 0; r < 7; r++) {
var line = [];
for (c = 0; c < 7; c++) {
line.push(RandomGenerator(50, 500));
}
board.push(line);
}
function showTable(c, chosen_col, chosen_row) {
var str = "";
str += "<table border=1>";
for (row = 0; row < 7; row++) {
str += "<tr>";
for (let col = 0; col < 7; col++) {
str += `<td>${board[row][col]}</td>`;
}
str += "</tr>";
}
str += "</table>";
document.getElementById("ff").innerHTML = str;
}
function RandomGenerator(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
showTable(-1);
var getUnique = function(){
var tdElements = document.querySelectorAll('#ff td');
tdElements[
RandomGenerator(0, tdElements.length)
].classList.add('uniqueCell');
// update the text of the cell using the class
document.querySelector('.uniqueCell').textContent = 'S';
};
getUnique();
var tds = document.querySelectorAll('td');
var isPlayerA = true;
var playerA = 0;
var playerB = 0;
tds.forEach(function(td){
td.addEventListener('click', function(){
document.querySelectorAll('.grn').forEach(td => td.classList.remove('grn'));
var col = this.cellIndex + 1;
var row = this.parentNode.rowIndex;
if(isPlayerA){
this.parentNode.querySelectorAll('td').forEach(td => td.classList.add('grn'));
isPlayerA = false;
playerA += Number(this.textContent);
}
else{
document.querySelectorAll(`td:nth-child(${col})`).forEach(c =>c.classList.add('grn'));
isPlayerA = true;
playerB += Number(this.textContent);
}
this.textContent = 'S';
this.classList.add('uniqueCell');
console.clear();
console.log(`Player A: ${playerA} :: Player B: ${playerB}`);
});
});
td{
border:2px solid black;
width:10px;
height:10px;
text-align: center;
}
td:hover{background-color:lightgreen;}
.grn{
background-color:green;
color:white;
}
.uniqueCell {
background-color: tomato;
}
<div id="ff"></div>
A function defined in setTimeOut only runs once in certain situations
I set up 3 inputs in ComboBox by which the user could set the grid size in the game. Selecting a value changes the rows and cols variables respectively, and then reboots the game by calling the init function.
The program starts normally, when I choose a different size the timer does not run the game more than once. When I change the size again it does work. If for example I change the sizes 6 times the game will only work in 3 of the times.
/* Game Of Life Application */
/* ------------------------ */
// initialize global variables
var rows = 55;
var cols = 140;
//initialize 2dim arrays
var arr;// current generation array
var nextArr; // next generation array
var mode = 0; //game current mode
var timeInMS = 40;
var timer;
//buttons selectors
var randomBtn = document.getElementById("randomBtnId");
var startBtn = document.getElementById("startBtnId");
var clearBtn = document.getElementById("clearBtnId");
var gridSize = document.getElementById("sizeId");
var container = document.getElementById("container");
function remove() {
let tb = document.querySelector("table");
tb.outerHTML = "";
}
gridSize.addEventListener("change",function(e) {
remove();
if (this.value === "Small") {
cols = 80;
rows = 20;
}
else if (this.value === "Medium") {
cols = 126;
rows = 34;
}
else {
cols = 140;
rows = 55;
}
timer = 0;
init();
});
//update the visual grid according to the states of the cell - live or dead.
function update() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var cell = document.getElementById(i + "_" + j);
if (arr[i][j] === 0) {
cell.setAttribute("class", "dead");
} else {
cell.setAttribute("class", "live");
}
}
}
}
//copy generation 0 array to generation 1. current arr gets the values of next arr
function copyAndResetGrid() {
console.log("in the reset grid");
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
arr[i][j] = nextArr[i][j];
nextArr[i][j] = 0;
}
}
}
//count number of neighbors for every cell - inputs are r - rows , c - columns
function countNeighbors(r, c) {
let rstart = 0, cstart = 0, rend = rows - 1, cend = cols - 1;
let count = 0;
if (r - 1 > 0)
rstart = r - 1;
if (c - 1 > 0)
cstart = c - 1;
if (r + 1 <= rend)
rend = r + 1;
if (c + 1 <= cend)
cend = c + 1;
for (let i = rstart; i <= rend; i++) {
for (let j = cstart; j <= cend; j++) {
if (arr[i][j] === 1)
count++;
}
}
count -= arr[r][c];
if (count < 0)
count = 0;
// console.log("number of live neighbors at : " + r + "," + c + " is : " + count);
return count;
}
// calculate next 2dim array (generation 1) according to gameOfLife rules
function calculateNext() {
let numOfLivesArr = 0;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
let currentMode = arr[i][j];
if (currentMode === 1)
numOfLivesArr++;
let count = countNeighbors(i, j);
if (currentMode === 0 && count === 3) {
nextArr[i][j] = 1;
}
else if (currentMode === 1 && (count < 2 || count > 3)) {
nextArr[i][j] = 0;
}
else {
nextArr[i][j] = currentMode;
}
}
}
// console.log("num of lives next: " + numOfLivesArr);
copyAndResetGrid();
//update();
}
//run game
function run() {
calculateNext();
update();
timer = setTimeout(run, 1000);
}
//populate the array with random values 0/1
function populateArr() {
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
arr[i][j] = Math.floor(Math.random() * 2);
if (arr[i][j] === 1) {
let cell = document.getElementById(i + "_" + j);
cell.setAttribute("class", "live");
}
else {
let cell = document.getElementById(i + "_" + j);
cell.setAttribute("class", "dead");
}
}
}
}
function deleteArr() {
}
//clear array - set 0 values for current and next generations arrays
function clear() {
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
arr[i][j] = 0;
nextArr[i][j] = 0;
}
}
//mode = 0;
}
function buttonsControl() {
randomBtn.addEventListener("click", function () {
clear();
populateArr();
});
startBtn.addEventListener("click", function () {
if (mode == 1) {
mode = 0;
startBtn.textContent = "Continue";
clearTimeout(timer);
}
else {
mode = 1;
startBtn.textContent = "Pause";
run();
}
});
clearBtn.addEventListener("click", function () {
startBtn.textContent = "Start";
clear();
update();
})
}
//draw table grid in the web page
function drawGrid() {
let grid = document.getElementById("container");
let table = document.createElement("table");
table.setAttribute("class", "center");
for (let i = 0; i < rows; i++) {
let tr = document.createElement("tr");
for (let j = 0; j < cols; j++) {
let cell = document.createElement("td");
cell.setAttribute("id", i + "_" + j);
cell.setAttribute("class", "dead");
tr.appendChild(cell);
cell.addEventListener("click", function () {
if (cell.classList.contains("live")) {
cell.setAttribute("class", "dead");
arr[i][j] = 0;
}
else
cell.setAttribute("class", "live");
arr[i][j] = 1;
});
}
table.appendChild(tr);
}
grid.appendChild(table);
}
//create 2 dim arrays - current and next generations.
function make2DArr() {
console.log("befire create arr !! ");
for (let i = 0; i < rows; i++) {
arr[i] = new Array(cols);
nextArr[i] = new Array(cols);
}
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
arr[i][j] = 0;
nextArr[i][j] = 0;
}
}
}
//initial game
function init() {
arr = new Array(rows);
nextArr = new Array(rows);
make2DArr();
drawGrid();
buttonsControl();
}
//load init function
window.onload = init();
body {
background-color: rgba(76, 77, 62, 0.514);
}
.center {
margin: auto;
width: 90%;
padding: 0.5rem;
position: relative;
}
#container {
margin: 0;
position: relative;
overflow: auto;
display: flex;
}
table {
border:1px rgb(241, 241, 241) solid;
border-spacing: 0;
position: absolute;
flex:1;
}
.live {
background-color:rgba(0, 0, 0, 0.685);
}
.dead {
background-color:rgba(228, 228, 241, 0.829);
}
td {
border:1px rgb(29, 182, 29) solid;
/* border-radius: 61px;*/
width: 10px;
height: 10px;
}
/* button {
margin-left: 0.5rem;
} */
button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 1rem 2rem;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 0.5rem 0.5rem;
transition-duration: 0.4s;
cursor: pointer;
}
button:hover {
background-color: rgba(144, 180, 145, 0.596);
color: rgb(54, 59, 54)
}
<body>
<div class="center">
<div id="container">
</div>
<button id="startBtnId"><span>Start</span></button>
<button id="clearBtnId"><span>Clear</span></button>
<button id="randomBtnId"><span>Random</span></button>
<select id="sizeId">
<option value="Big">Big</option>
<option value="Medium">Medium</option>
<option value="Small">Small</option>
</select>
</div>
<script type="text/javascript" src="game.js"></script>
</body>
the timer is work only in even number of mode selection and does not work in odd number of mode selection.
for example , if i changed the mode 4 times : work -> not -> word -> not
Once an option has been selected from the list, init function was called. Within the function I called for 3 functions that build the arrays, initialize the board and create the button events listeners. The solution is to build the arrays and initialize the board without create the buttons event listeners again. so i just calld make2darray and drawgrid functions.
I have a grid with a player, yellow box, and obstacles (.ob) and black boxes. I don't want the player to go in the obstacle squares when I click the 'UP' button.
I was thinking to check if the next class has .ob do not go there. Any suggestions?
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 50; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var obstacles = [];
while (obstacles.length < 20) {
var randomIndex = parseInt(49 * Math.random());
if (obstacles.indexOf(randomIndex) === -1) {
obstacles.push(randomIndex);
var drawObstacle = document.getElementById('square' + randomIndex);
$(drawObstacle).addClass("ob")
}
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(49 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
#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;
}
.p-1 {
background-color: yellow;
}
.ob {
background-color: black;
}
<div id="grid-box"></div>
<div class="move">
<button id="button_up">UP</button><br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
jsFifddle
Use the following code
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
var idUpMove = 'square' + idMove;
if($('#' + idUpMove).hasClass('ob')){
return false;
}
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
Here we check the next selected class having ".ob" class if its return true then we stop the process if it returns false then process continues
if($('#' + idUpMove).hasClass('ob')){
return false;
}
Fiddle
I am building a table and I want the background color of the selected cell to change. Then when i select a different cell (and apply the same change to this new cell), I want the change to revert in the first (no longer selected) cell. What is the best approach to this? Here is my code:
var table = '';
for (var r = 0; r < rows; r++) {
table += '<tr>';
for (var c = 0; c < cols; c++) {
if (c == 0) {
if (r == 0) {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px;">' + '</td>';
}
else {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px">' + r + '</td>';
}
}
else if (r == 0 && c > 0) {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px">' + letterArray[c - 1] + '</td>';
}
else {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td id="' + cellID + '" style="min-width:50px; height:25px;" onclick="selectCell(this)">' + '</td>';
}
}
table += '</tr>';
}
Writing the table to the document:
document.write('<table id="table" border=1>' + table + '</table>');
selectCell function:
function selectCell(x) {
alert("Row = " + x.parentNode.rowIndex + " Col = " + String.fromCharCode((x.cellIndex - 1) + 65));
x.style.backgroundColor = 'purple';
}
This is where i encounter my problem. As I click the first cell, my alert shows me the info of which cell i have selected, and then changes the background color. Then when i select a different cell, it alerts me with the new cell row and column info, and changes the color.
What is the best way to revert the color change of the previously selected cell?
Thank you for your time and energy!
You should make a CSS class that applies the background color and add/remove it in your function. Your function can check for an element that already has the class, like this:
CSS:
.selected {
background-color: purple;
}
JS:
function selectCell(x) {
var currentSelection = document.querySelector('.selected');
if (currentSelection) {
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
}
I agree with #Rishat Muhametshin that you should avoid using document.write. And I liked how #skyline3000 solved it so I put everything together into a snippet for you to see a cleaner way to code this.
I even went so far as to give you true headers on the top and the side and then added extra CSS to make them look more like headers.
var rows = 7;
var cols = 8;
var table = document.createElement('table');
var selecedTd;
table.id = "table";
table.border = 1;
table.cellSpacing = 0;
table.cellPadding = 4;
document.body.appendChild(table);
for (var r = 0; r < rows; r++) {
var tr = document.createElement('tr');
if (r > 0) {
tr.id = "row"+r;
}
table.appendChild(tr);
for (var c = 0; c < cols; c++) {
var cell;
var char = String.fromCharCode(c+64);
if (c===0 || r===0) {
cell = document.createElement('th');
cell.setAttribute('style', 'min-width:50px; height:25px;');
} else {
cell = document.createElement('td');
}
tr.appendChild(cell);
if (c == 0 && r > 0) {
cell.textContent = r;
}
else if (r == 0) {
if (c > 0) {
cell.textContent = char
cell.id = "col"+c;
}
}
else {
cell.id = r+char;
cell.addEventListener('click', selectCell);
//cell.textContent = cell.id;
}
}
}
function selectCell(event) {
var x = event.target;
var currentSelection = document.querySelector('.selected');
if (currentSelection) {
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
}
.selected {
background-color: purple;
color: white;
}
th {
background-color: #DDD;
}
td {
cursor: pointer;
}
UPDATE
Below is code that will allow editing of the selected field. It needs work before it could be used in production and you would want to save the data in some array or object as well as in the cells, but it should get you going.
var rows = 7;
var cols = 8;
var table = document.createElement('table');
var selecedTd;
var inputField = document.createElement('input');
table.id = "table";
table.border = 1;
table.cellSpacing = 0;
table.cellPadding = 4;
document.body.appendChild(table);
inputField.className = "roving-input";
for (var r = 0; r < rows; r++) {
var tr = document.createElement('tr');
if (r > 0) {
tr.id = "row"+r;
}
table.appendChild(tr);
for (var c = 0; c < cols; c++) {
var cell;
var char = String.fromCharCode(c+64);
if (c===0 || r===0) {
cell = document.createElement('th');
} else {
cell = document.createElement('td');
}
tr.appendChild(cell);
if (c == 0 && r > 0) {
cell.textContent = r;
}
else if (r == 0) {
if (c > 0) {
cell.textContent = char
cell.id = "col"+c;
}
}
else {
cell.id = r+char;
cell.addEventListener('click', selectCell);
cell.textContent = cell.id;
}
}
}
function selectCell(event) {
var x = event.target;
var currentSelection = document.querySelector('.selected');
if (x !== currentSelection && x.localName === 'td') {
if (currentSelection) {
currentSelection.textContent = inputField.value;
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
inputField.value = x.textContent;
x.appendChild(inputField);
inputField.style.width = (x.clientWidth-2)+'px';
inputField.focus();
inputField.select();
}
}
.selected {
position: relative;
}
th {
background-color: #DDD;
height:25px;
min-width:50px;
}
td {
cursor: pointer;
}
.roving-input {
background-color: #FDF;
border: none;
bottom: 0;
display: inline-block;
left: 0;
outline: none;
position:absolute;
right: 0;
top: 0;
}