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>
Related
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.
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>
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;
}
This HTML and Javascript combined are supposed to form bars that are the height of the numbers entered in the prompt, relative to each other. The bars are not appearing when the numbers are entered. What do I need to fix in my code in order to make the bars appear?
"use strict";
window.onload=function()
{
var userValue;
var i;
var j;
var k;
var error;
var correct;
j = 0;
k = 0;
error = new Array(j);
correct = new Array(k);
userValue = window.prompt("Insert values separated by comma, whitespace, or both.");
userValue = packArray(trimElements(toArray(userValue, " ,")));
for(i = 0; i < userValue.length; i++)
{
if(isNumeric(userValue[i]) === false)
{
error[j] = userValue[i];
j = j + 1;
}
else
{
correct[k] = userValue[i];
k = k + 1;
}
}
if(error.length > 0)
{
window.alert("Error: " + error);
}
else
{
createGraph(userValue, document.getElementById("positiveQuadrant"));
}
};
function toArray(data, delimiters)
{
var locArray;
var result;
var i;
var dataArray;
var start;
locArray = findPositions(data, delimiters);
result = "";
i = 0;
if(data === null)
{
data = "";
}
else
{
result = result + data;
}
if(delimiters === null)
{
delimiters = "";
}
else
{
result = result + delimiters;
}
if(delimiters.length === 0)
{
delimiters = delimiters + " \t\r\n\f";
}
dataArray = new Array(locArray.length + 1);
start = 0;
while(i < dataArray.length)
{
dataArray[i] = data.substring(start, locArray[i]);
start = locArray[i] + 1;
i = i + 1;
}
return dataArray;
}
function findPositions(someString, lookForThis)
{
var i;
var result;
var count;
result = new Array(count);
i = 0;
count = 0;
while(i < someString.length)
{
if(lookForThis.indexOf(someString.charAt(i)) >= 0)
{
result[count] = someString.indexOf(lookForThis.charAt(i), (i + 1) - 1);
count = count + 1;
}
i = i + 1;
}
return result;
}
function trimElements(array)
{
var i;
var trimArray;
trimArray = new Array(array.length);
i = 0;
while(i < array.length)
{
trimArray[i] = trim(array[i]);
i = i + 1;
}
return trimArray;
}
function packArray(array)
{
var i;
var count;
var packedArray;
i = 0;
count = 0;
packedArray = new Array(count);
while(i < array.length)
{
if(array[i] !== null && array[i] !== "")
{
packedArray[count] = array[i];
count = count + 1;
}
i = i + 1;
}
return packedArray;
}
function convertToNumber(array)
{
var i;
var result;
i = 0;
result = "";
while(i < array.length)
{
if(isNumeric(array[i]) === true)
{
array[i] = Number(array[i]);
}
else
{
result = result + " " + array[i];
}
i = i + 1;
}
return trim(result);
}
function trim(data)
{
var start;
var whitespace;
var end;
var result;
if(typeof data==="string")
{
whitespace=" \n\r\t\f";
start=0;
}
else
{
result=data;
}
while((start<data.length)&&(whitespace.indexOf(data.charAt(start))))
{
start=start+1;
};
end=data.length-1;
while((end>=0)&&(whitespace.indexOf(data.charAt(end))))
{
end=end-1;
};
if(end<start)
{
result="";
}
else
{
result=data.substring(1+start,end);
}
return result;
};
function createHTMLElement(elementType, id, classInfo, content)
{
if(elementType===null)
{
elementType="";
};
trim(elementType);
if(id===null)
{
id="";
}
trim(id);
if(id.length>0)
{
id=" "+"id="+'"'+id+'"'+" ";
};
if(classInfo===null)
{
classInfo="";
}
trim(classInfo);
if(classInfo.length>0)
{
classInfo=" "+ "class="+'"'+classInfo+'"';
}
if(content===null)
{
content="";
};
trim(content);
return '<' +elementType +
id + classInfo +
'>' + content +
'</' + elementType + '>';
};
function isNumeric(data)
{
return isNaN(data);
};
function getRandomInteger(upperLimit)
{
return Math.floor(Math.random()*(upperLimit+1));
};
function getRandomRGB()
{
var blue;
var green;
var red;
red=getRandomInteger(255);
blue=getRandomInteger(255);
green=getRandomInteger(255);
return"rgb("+red+","+green+","+blue+")";
};
function createScaledArray(array, scaleFactor)
{
var i;
var scaledArray;
scaledArray = new Array(array.length);
for(i = 0; i < array.length; i++)
{
scaledArray[i] = (array[i] / scaleFactor);
}
return scaledArray;
}
function createGraph(array, quadReference)
{
var i;
var loc;
var scaleFactor;
var scaleArray;
var html;
var element;
var elementTop;
if(array.length > 0)
{
loc = 0;
for(i = 0; i < array.length; i++)
{
if(Number(array[i]) > Number(array[loc]))
{
loc = i;
}
}
scaleFactor = Math.abs(array[loc]);
scaleArray = createScaledArray(array, scaleFactor);
html = "";
for(i = 0; i < scaleArray.length; i++)
{
html = html + createHTMLElement("div", "columnContainer", "columnContainer", createHTMLElement("div", "coloredArea" + i, "coloredArea", createHTMLElement("div", "dataValue", "dataValue", array[i])));
}
quadReference.innerHTML = html;
for(i = 0; i < scaleArray.length; i++)
{
element = document.getElementById("coloredArea" + i);
elementTop = (100 - (scaleArray[i] * 100));
if(elementTop > 100)
{
elementTop = elementTop + (scaleArray[i] * 100);
}
element.style.top = elementTop + "%";
element.style.height = Math.abs(scaleArray[i] * 100) + "%";
element.style.backgroundColor = getRandomRGB();
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title> Graphing </title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<script src="Graphing.js" type="text/javascript"></script>
<style type="text/css">
{
border : 0;
margin : 0;
padding : 0;
}
body
{
font-family : "Times New Roman", serif;
font-size : 12pt;
}
.positiveQuadrant
{
height:12em;
width:2em;
border-right:solid black 3px;
}
.negativeQuadrant
{
position:relative;
height:2em;
width:22em;
border-top:solid black 3px;
bottom:2em;
}
.columnContainer
{
position: relative;
float: left;
height: 10em;
width: 1.5em;
margin: 1px;
}
.coloredArea
{
position: relative;
background-color: red;
}
.dataValue
{
font-size: 12pt;
text-align: center;
position: relative;
top: -16px;
}
</style>
</head>
<body>
<div class ="positiveQuadrant" id="positiveQuadrant"></div>
<div class = "negativeQuadrant" id ="negativeQuadrant"></div>
</body>
</html>
I am trying to make a chess game. So far i have only made the white pawns moveable (you move them by dragging them to where you want them to go). However, only the first move works. Why does this happen? I use
$(".piece").mousedown(function(){}
, but it is only called once.
The problem is $("#" + tileFn).append($("#" + tileIn).html()); which creates a new piece element, to whom the mousedown handler is not attached.
One solution is to use event deletagation, or instead of creating a new element just move the existing element like
function parent(element) {
var parentID = $(element).parent().attr("ID");
var parentClass = $(element).parent().attr("class");
var parentType = $(element).parent().get(0).nodeName;
if (parentID != null) {
return ("#" + parentID);
} else if (parentClass != null) {
return ("." + parentClass);
} else {
if (parentType.toLowerCase() == "body") {
parentType = document;
return parentType;
} else {
return parentType;
}
}
}
var dimensions = 600; // must be divisible by 8
var tile1 = "<div class='tile tile1' id='";
var tile2 = "<div class='tile tile2' id='";
var end = "'></div>";
var multiplicity = "";
var tileIn = "";
var tileFi = "";
var classes = "";
var color = "";
var type = "";
var possible = [];
$(document).ready(function() {
//setup start
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
row = i * 2 + 1;
column = j * 2 + 1;
$("#container").append(tile1 + row + column + end + tile2 + row + (column + 1) + end);
}
for (var k = 0; k < 4; k++) {
row = i * 2 + 2;
column = k * 2 + 1;
$("#container").append(tile2 + row + column + end + tile1 + row + (column + 1) + end);
}
}
$("#container").css({
height: dimensions,
width: dimensions
});
$(".tile").css({
height: dimensions / 8,
width: dimensions / 8
});
$(".piece").css({
height: dimensions / 8,
width: dimensions / 8
});
$("<div class='b p piece'><img src='bp.icns' height='69'></div>").appendTo("#21, #22, #23, #24, #25, #26, #27, #28");
$("<div class='b r piece'><img src='br.icns' height='69'></div>").appendTo("#11, #18");
$("<div class='b n piece'><img src='bn.icns' height='69'></div>").appendTo("#12, #17");
$("<div class='b b piece'><img src='bb.icns' height='69'></div>").appendTo("#13, #16");
$("<div class='b k piece'><img src='bk.icns' height='69'></div>").appendTo("#14");
$("<div class='b q piece'><img src='bq.icns' height='69'></div>").appendTo("#15");
$("<div class='w p piece'><img src='wp.icns' height='69'></div>").appendTo("#71, #72, #73, #74, #75, #76, #77, #78");
$("<div class='w r piece'><img src='wr.icns' height='69'></div>").appendTo("#81, #88");
$("<div class='w n piece'><img src='wn.icns' height='69'></div>").appendTo("#82, #87");
$("<div class='w b piece'><img src='wb.icns' height='69'></div>").appendTo("#83, #86");
$("<div class='w q piece'><img src='wq.icns' height='69'></div>").appendTo("#84");
$("<div class='w k piece'><img src='wk.icns' height='69'></div>").appendTo("#85");
//setup end
$(".piece").mousedown(function() {
tileIn = parent($(this)).substr(1, 2);
classes = $(this).attr("class");
color = classes.charAt(0);
type = classes.charAt(2);
y = tileIn.charAt(0);
x = tileIn.charAt(1);
//white start
if (color == "w") {
//white pawn start
if (type == "p") {
if (y == "7") {
possible = ["6" + x, "5" + x];
} else {
possible = [(y - 1) + x];
}
return;
}
//white pawn end
//
else if ("a" == "b") {
}
}
//white end
//black start
else {
}
//white end
});
$(".tile").mouseup(function() {
tileFn = $(this).attr("id");
if (jQuery.inArray(tileFn, possible) !== -1 && $(this).is(':empty')) {
$("#" + tileFn).append($("#" + tileIn).contents());
} else {}
possible = [];
});
});
* {
user-drag: none;
-moz-user-select: none;
-webkit-user-drag: none;
}
#container {
margin: 0 auto;
border: 1px solid gray;
}
.tile {
float: left;
}
.tile1 {
background-color: white;
}
.tile2 {
background-color: rgba(0, 0, 0, 0.58);
}
.piece {
padding: 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css">
<div id="container"></div>
The selector $(".piece") only selects the fields which has pices on it at the time you execute the statement. You will have to add the function to the fields as the pieces are moved on the board.
So you mouseup function should probably set the call back for the piece on the new field.