Indicator error in tic tac toe javascript - javascript

I am having problem based on the indicator created in my tic tac toe javascript codes. can you help me solve it?
cell.indicator = indicator;
the console mentioned this
Uncaught TypeError: Cannot set property 'indicator' of null
at onload (javascript.js:54)
here are the codings.
var squares =[];
var EMPTY = '\xA0'
var score;
var moves;
var turn = 'X';
var wins = [ 119, 8064, 516096, 17930144, 2113929216, (1.352914698*10^10),
2181570690, 4363141380,8726282760,(1.745256552*10^10), (3.490513104*10^10),
(6.981026208*10^10),(96.926057496*10^10), 2216757312];
var startNewGame = function (){
turn = 'X';
score = {'X': 0 , 'O': 0};
moves =0;
for (var i = 0; i < squares.length; i += 1){
squares[i].firstChild.nodeValue = EMPTY;
}
};
var win = function (score){
for (var i = 0; i < wins.length; i++){
if ((wins[i] & score) == wins[i]){
}
}
return false;
};
var set = function(){
if (this.firstChild.nodeValue !== EMPTY){
return;
}
this.firstChild.nodeValue = turn;
moves += 1;
score[turn] += this.indicator;
if (win(score[turn])){
alert(turn + "wins!");
startNewGame();
}
else if (moves === 36){
alert("Beemo\u2019s game!");
startNewGame();
}
else {
turn = turn === 'X' ? 'O' : 'X';
}
};
onload = function(){
var indicator = 1;
for (var i = 0; i < 6; i++){
for (var j = 0; j < 6; j++){
var cell = document.getElementById("cell" + i + j);
cell.indicator = indicator;
cell.onclick = set;
cell.appendChild(document.createTextNode(''));
squares.push(cell);
indicator += indicator;
}
}
startNewGame();
};
here's the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>ULTIMATE TIC TAC TOE</title>
<script src="javascript.js"></script>
<style type="text/css">
h1{
text-align: center;
}
table{
border: outset 1px rgb(200, 200, 200)
}
td{
width: 50px;
height: 50px;
vertical-align: middle;
border: inset 1px rgb(200,200,200)
}
tr{
text-align: center;
}
</style>
</head>
<body>
<h1>Tic Tac Toe</h1>
<table align="center">
<tr>
<td id cell="cell00"></td>
<td id cell="cell01"></td>
<td id cell="cell02"></td>
<td id cell="cell03"></td>
<td id cell="cell04"></td>
<td id cell="cell05"></td>
</tr>
<tr>
<td id cell="cell10"></td>
<td id cell="cell11"></td>
<td id cell="cell12"></td>
<td id cell="cell13"></td>
<td id cell="cell14"></td>
<td id cell="cell15"></td>
</tr>
<tr>
<td id cell="cell20"></td>
<td id cell="cell21"></td>
<td id cell="cell22"></td>
<td id cell="cell23"></td>
<td id cell="cell24"></td>
<td id cell="cell25"></td>
</tr>
<tr>
<td id cell="cell30"></td>
<td id cell="cell31"></td>
<td id cell="cell32"></td>
<td id cell="cell33"></td>
<td id cell="cell34"></td>
<td id cell="cell35"></td>
</tr>
<tr>
<td id cell="cell40"></td>
<td id cell="cell41"></td>
<td id cell="cell42"></td>
<td id cell="cell43"></td>
<td id cell="cell44"></td>
<td id cell="cell45"></td>
</tr>
<tr>
<td id cell="cell50"></td>
<td id cell="cell51"></td>
<td id cell="cell52"></td>
<td id cell="cell53"></td>
<td id cell="cell54"></td>
<td id cell="cell55"></td>
</tr>
</table>
</body>
</html>

The cells you're looking for cannot be found because all of their id attributes are empty, so document.getElementById("cell" + i + j) returns nothing. Change to <td id="cellxx"> and you'll be fine.
Then you will probably find that an HTML element doesn't have a property indicator; look into using the data- property instead: cell.setAttribute('data-indicator', indicator). You should also modify your set() method to read that property instead.

Related

Looping through table cell ids in Javascript

I have created table cells in html that have ids that increment by 1 for example: cell1, cell2, cell3, ......, cell100.
What I would like to do is loop through and get reference to each of these cells using a for loop because referencing them one by one won't be good pratice and will require alot of codes of line, instead of this;
var cell1 = document.getElementById('cell1');
var cell2 = document.getElementById('cell2');
var cell3 = document.getElementById('cell3');
......
var cell100 = document.getElementById('cell100');
Is it possible to do something like this?
for (i = 0; i<=100; i++) {
var cell+i = document.getElementById("cell"+i);
// then I can call individual cells and assign tasks to them something along the lines of;
cell1.addEventListener('input',function(){}
cell5.background = '#f5f5f5'
cell55.innerHTML = 'I am cell 55'
etc..
}
EDITED:
Incase it might be useful, I have 1 table that contains many cells of which some have ids and some don't. I would only like to reference the ones that do have ids.
you can use document.querySelectorAll with a wildcard
var slice = Array.prorotype.slice;
var selection = document.querySelectorAll("[id^=cell]");
slice.call(selection).forEach(function(item, index){
// here item is the table row and index is the iteration number of forEach
// to get the id
var id = item.id;
//to get the numerical value in id
var number_in_id = item.id.match(/\d+/g)[0];
})
document.querySelectorAll("[id^=cell]") selectects all elements that their id starts with the string cell if you want to make it specific for table td's you add document.querySelectorAll("td[id^=cell]")
may be you are looking for this
var grid = document.getElementById("grid");//grid is the id of the table
for (var i = 1, row; row = grid.rows[i]; i++)
row.cells[0].textContent = "";//content of the starts with row 1..2..3 and so one than cell[0] or cell[1] and so on.
It'd be good pratice to use classes, though;
In base of your loop, you can do it so to get the current element, but if you have an loop more longer than the amount of the elements id numbers sequence, then it will be returning errors.
var Cell=document.getElementById("cell"+i)
//you've your DOM element in the variable called Cell now
//the one error you did is in the variable name
//you used the + operator in the variable name;
That's equivalent to element with id "cell0" when it's the first execution time of the loop. Not too elegant, you've many other ways to do the same.
Yes, it is quite easy, see below.
var cells = [];
for (var i = 0; i <= 100; i++) {
cells[i] = document.getElementById("cell"+i);
// do stuff....
if( cells[55] ) {
cells[55].innerHTML = 'I am cell 55';
}
}
Consider you have a table with an ID as myTable.
Get the table with,,
var theTable = document.getElementById('myTable');
To get all <td>s you could do,
var cells = theTable.querySelectorAll('td');
Then do the looping part,
for(var i = 0; i < cells.length; i++){
if(cells[i].id && cells[i].id.indexOf('cell') != -1){ //added to get only the significant cells
//do your stuff
cells[i].addEventListener(function(){});
cells[i].innerHTML = 'Something';
}
}
I'm lazy and didn't want to hand code any table, so I made Demo 2:
A form that'll accept a number of rows and columns
Can create <tr> and append to a table (0 to 100 rows)
Can create <td> and append to a <tr>(0 to 100 columns)
Assigns a unique id to every <tr> and <td>
The id pattern allows a human reader to locate <tr>s and <td>s
Each id for the <td> are displayed in each cell.
There's also two arrays, one for the <tr>(rowX) and one for the <td>(colY). There's many powerful methods for Array and having those 2 arrays you could even make a two-dimensional array.
Concerning the OP's request specifically about an id for cells on a table (complete or partial), I am aware that you have a pre-made table, so I'll take the key lines that make it possible in Demo 2 to assign ids:
row.setAttribute('id', 'r' + r);// Each row will have a numbered id (ex. r0 is row 1)
col.setAttribute('id', 'r' + r + 'c' + c);// Each cell will have a numbered id representing it's location (ex. r3c0 is located on row 4 column 1)
Demo 1
This snippet is an adaptation of the code previously mentioned:
function oddRows() {
var rows = document.querySelectorAll('tr');
// rows is a NodeList (an array-like object).
// We can covert this NodeList into an Array.
var rowArray = Array.prototype.slice.call(rows);
//Either way, NodeList or Array should be iterated through a for loop (most common way to reiterate)
for (var i = 0; i < rowArray.length; i++) {
if (i % 2 === 1) {
console.log(i);
var odd = rowArray[i];
odd.style.display = "none";
//This filters and removes all odd numbered rows
}
}
return false;
}
function evenCols() {
var cols = document.querySelectorAll('td');
var colArray = Array.prototype.slice.call(cols);
for (var j = 0; j < colArray.length; j++) {
if (j % 2 === 0) {
console.log(j);
var even = colArray[j];
even.style.backgroundColor = "red";
//This filters even numbered <td> and colors the background red.
}
}
return false;
}
td {
border: 2px inset #777;
}
button {
margin: 20px 5px 10px;
}
<button id="btn1" onclick="oddRows();">Remove Odd Rows</button>
<button id="btn2" onclick="evenCols();">Mark Even Cols</button>
<table id="t1">
<tr id="r0" class="row">
<td id="r0c0" class="col">r0c0</td>
<td id="r0c1" class="col">r0c1</td>
<td id="r0c2" class="col">r0c2</td>
<td id="r0c3" class="col">r0c3</td>
<td id="r0c4" class="col">r0c4</td>
<td id="r0c5" class="col">r0c5</td>
<td id="r0c6" class="col">r0c6</td>
<td id="r0c7" class="col">r0c7</td>
<td id="r0c8" class="col">r0c8</td>
<td id="r0c9" class="col">r0c9</td>
</tr>
<tr id="r1" class="row">
<td id="r1c0" class="col">r1c0</td>
<td id="r1c1" class="col">r1c1</td>
<td id="r1c2" class="col">r1c2</td>
<td id="r1c3" class="col">r1c3</td>
<td id="r1c4" class="col">r1c4</td>
<td id="r1c5" class="col">r1c5</td>
<td id="r1c6" class="col">r1c6</td>
<td id="r1c7" class="col">r1c7</td>
<td id="r1c8" class="col">r1c8</td>
<td id="r1c9" class="col">r1c9</td>
</tr>
<tr id="r2" class="row">
<td id="r2c0" class="col">r2c0</td>
<td id="r2c1" class="col">r2c1</td>
<td id="r2c2" class="col">r2c2</td>
<td id="r2c3" class="col">r2c3</td>
<td id="r2c4" class="col">r2c4</td>
<td id="r2c5" class="col">r2c5</td>
<td id="r2c6" class="col">r2c6</td>
<td id="r2c7" class="col">r2c7</td>
<td id="r2c8" class="col">r2c8</td>
<td id="r2c9" class="col">r2c9</td>
</tr>
<tr id="r3" class="row">
<td id="r3c0" class="col">r3c0</td>
<td id="r3c1" class="col">r3c1</td>
<td id="r3c2" class="col">r3c2</td>
<td id="r3c3" class="col">r3c3</td>
<td id="r3c4" class="col">r3c4</td>
<td id="r3c5" class="col">r3c5</td>
<td id="r3c6" class="col">r3c6</td>
<td id="r3c7" class="col">r3c7</td>
<td id="r3c8" class="col">r3c8</td>
<td id="r3c9" class="col">r3c9</td>
</tr>
<tr id="r4" class="row">
<td id="r4c0" class="col">r4c0</td>
<td id="r4c1" class="col">r4c1</td>
<td id="r4c2" class="col">r4c2</td>
<td id="r4c3" class="col">r4c3</td>
<td id="r4c4" class="col">r4c4</td>
<td id="r4c5" class="col">r4c5</td>
<td id="r4c6" class="col">r4c6</td>
<td id="r4c7" class="col">r4c7</td>
<td id="r4c8" class="col">r4c8</td>
<td id="r4c9" class="col">r4c9</td>
</tr>
<tr id="r5" class="row">
<td id="r5c0" class="col">r5c0</td>
<td id="r5c1" class="col">r5c1</td>
<td id="r5c2" class="col">r5c2</td>
<td id="r5c3" class="col">r5c3</td>
<td id="r5c4" class="col">r5c4</td>
<td id="r5c5" class="col">r5c5</td>
<td id="r5c6" class="col">r5c6</td>
<td id="r5c7" class="col">r5c7</td>
<td id="r5c8" class="col">r5c8</td>
<td id="r5c9" class="col">r5c9</td>
</tr>
<tr id="r6" class="row">
<td id="r6c0" class="col">r6c0</td>
<td id="r6c1" class="col">r6c1</td>
<td id="r6c2" class="col">r6c2</td>
<td id="r6c3" class="col">r6c3</td>
<td id="r6c4" class="col">r6c4</td>
<td id="r6c5" class="col">r6c5</td>
<td id="r6c6" class="col">r6c6</td>
<td id="r6c7" class="col">r6c7</td>
<td id="r6c8" class="col">r6c8</td>
<td id="r6c9" class="col">r6c9</td>
</tr>
<tr id="r7" class="row">
<td id="r7c0" class="col">r7c0</td>
<td id="r7c1" class="col">r7c1</td>
<td id="r7c2" class="col">r7c2</td>
<td id="r7c3" class="col">r7c3</td>
<td id="r7c4" class="col">r7c4</td>
<td id="r7c5" class="col">r7c5</td>
<td id="r7c6" class="col">r7c6</td>
<td id="r7c7" class="col">r7c7</td>
<td id="r7c8" class="col">r7c8</td>
<td id="r7c9" class="col">r7c9</td>
</tr>
<tr id="r8" class="row">
<td id="r8c0" class="col">r8c0</td>
<td id="r8c1" class="col">r8c1</td>
<td id="r8c2" class="col">r8c2</td>
<td id="r8c3" class="col">r8c3</td>
<td id="r8c4" class="col">r8c4</td>
<td id="r8c5" class="col">r8c5</td>
<td id="r8c6" class="col">r8c6</td>
<td id="r8c7" class="col">r8c7</td>
<td id="r8c8" class="col">r8c8</td>
<td id="r8c9" class="col">r8c9</td>
</tr>
<tr id="r9" class="row">
<td id="r9c0" class="col">r9c0</td>
<td id="r9c1" class="col">r9c1</td>
<td id="r9c2" class="col">r9c2</td>
<td id="r9c3" class="col">r9c3</td>
<td id="r9c4" class="col">r9c4</td>
<td id="r9c5" class="col">r9c5</td>
<td id="r9c6" class="col">r9c6</td>
<td id="r9c7" class="col">r9c7</td>
<td id="r9c8" class="col">r9c8</td>
<td id="r9c9" class="col">r9c9</td>
</tr>
</table>
If ids seem too heavy and cumbersome, you can select any cell on a table by using the pseudo-selectors nth-child and nth-of-type.
Example:
Target:* You want the 3rd <td> on the 5th row to have red text.
CSS:
table tbody tr:nth-of-type(5) td:nth-of-type(3) { color: red; }
jQuery:
$("table tbody tr:nth-of-type(5) td:nth-of-type(3)").css('color', 'red');
JavaScript:
var tgt = document.querySelector("table tbody tr:nth-of-type(5) td:nth-of-type(3)");
tgt.style.color = "red";
*Assuming that the target element has a table with a <tbody>
Demo 2
fieldset {
width: 50vw;
height: 55px;
margin: 10px auto;
padding: 3px;
}
input {
width: 40px;
height: 20px;
margin: 5px 10px;
}
table {
table-layout: fixed;
border-collapse: collapse;
border: 3px ridge #666;
width: 50vw;
height: 50vh;
margin: 20px auto;
}
td {
height: 20px;
width: 20px;
border: 1px inset grey;
font-size: 8px;
}
<fieldset>
<legend>Rows & Columns</legend>
<input id="rows" type="number" min="0" max="100" />
<input id="cols" type="number" min="0" max="100" />
<button id="btn1">Build</button>
</fieldset>
<table id="t1"></table>
<script>
var t1 = document.getElementById('t1');
var rows = document.getElementById('rows');
var cols = document.getElementById('cols');
var btn1 = document.getElementById('btn1');
btn1.addEventListener('click', function(e) {
var R = rows.value;
var C = cols.value;
var rowX = [];
var colY = [];
for (var r = 0; r < R; r++) {
var row = document.createElement('tr');
row.setAttribute('id', 'r' + r);// Each row will have a numbered id (ex. r0 is row 1)
row.classList.add('row');
rowX.push(row);
t1.appendChild(row)
for (var c = 0; c < C; c++) {
var col = document.createElement('td');
col.setAttribute('id', 'r' + r + 'c' + c);// Each cell will have a numbered id representing it's location (ex. r3c0 is located on row 4 column 1)
col.innerHTML = col.id;
col.classList.add('col');
colY.push(col);
row.appendChild(col);
}
}
}, false);
</script>

Reset board on Tic-Tac-Toe

I'm trying my hand at building a tic-tac-toe game with plain vanilla Javascript, so I'm hoping we can stay in the boundaries of keeping it simple Javascript. Do not optimize code, trying to learn the hard way!
What I require is the following: After all squares have been filled, an alert box appears "All squares filled!" <-- This part is done. After the user clicks on the OK box, a reset button appears towards the bottom of the board. This reset button will reset the board so the game can be played again. After clicking the reset button, the board should reset and the reset button should disappear.
I have started the function called 'function resetButton'. If you need further clarification, please advise.
Thank you!
Here is the code I have got so far:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tic Tac Toe</title>
<style>
td {
border: 1px solid black;
height: 250px;
width: 250px;
font-family: sans-serif;
font-size: 150pt;
text-transform: uppercase;
}
</style>
</head>
<body>
<table>
<tr>
<td align="center" id="square1" onclick="displayMarker('square1');"></td>
<td align="center" id="square2" onclick="displayMarker('square2');"></td>
<td align="center" id="square3" onclick="displayMarker('square3');"></td>
</tr>
<tr>
<td align="center" id="square4" onclick="displayMarker('square4');"></td>
<td align="center" id="square5" onclick="displayMarker('square5');"></td>
<td align="center" id="square6" onclick="displayMarker('square6');"></td>
</tr>
<tr>
<td align="center" id="square7" onclick="displayMarker('square7');"></td>
<td align="center" id="square8" onclick="displayMarker('square8');"></td>
<td align="center" id="square9" onclick="displayMarker('square9');"></td>
</tr>
</table>
<script>
var cp1 = 1;
function displayMarker(allSquares) {
if (document.getElementById(allSquares).innerHTML != "") {
alert("Choose another square");
}
else {
if (cp1 == 1) {
document.getElementById(allSquares).innerHTML = "X";
cp1 = 2;
}
else {
document.getElementById(allSquares).innerHTML = "O";
cp1 = 1;
}
}
checkEmpty();
}
function checkEmpty() {
var anyEmpty = false;
for (var i = 1; i <= 9; i++) {
if (document.getElementById('square' + i).innerHTML == "") {
anyEmpty = true;
}
}
if (!anyEmpty)
alert("All squares filled!");
resetButton();
}
function resetButton() {
var button = document.createElement("button");
button.innerHTML = "Reset";
button.addEventListener("click", function () {
alert("Board Reset");
});
}
</script>
</body>
</html>
Try something like this..
button.addEventListener("click", function () {
var tds = document.getElementsByTagName('td');
for(var i = 0; i < tds.length; i++) {
tds[i].innerHTML = ''
}
});

Tic-Tac-Toe: Checking Empty Squares [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I’m trying my hand at building a tic-tac-toe game with plain JavaScript.
What I require is the following: I need code that will check each square to see if it’s filled with an X or an O. If squares are still available, no need for an alert but if all squares are filled, I need it to alert “No more moves!”.
I have started the function checkEmpty.
Here is the code I have got so far:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tic Tac Toe</title>
<style>
td {
border: 1px solid black;
height: 250px;
width: 250px;
font-family: sans-serif;
font-size: 150pt;
text-transform: uppercase;
}
</style>
</head>
<body>
<table>
<tr>
<td align="center" id="square1" onclick="displayMarker('square1');"></td>
<td align="center" id="square2" onclick="displayMarker('square2');"></td>
<td align="center" id="square3" onclick="displayMarker('square3');"></td>
</tr>
<tr>
<td align="center" id="square4" onclick="displayMarker('square4');"></td>
<td align="center" id="square5" onclick="displayMarker('square5');"></td>
<td align="center" id="square6" onclick="displayMarker('square6');"></td>
</tr>
<tr>
<td align="center" id="square7" onclick="displayMarker('square7');"></td>
<td align="center" id="square8" onclick="displayMarker('square8');"></td>
<td align="center" id="square9" onclick="displayMarker('square9');"></td>
</tr>
</table>
<script>
forLoop();
var cp1 = 1;
function displayMarker(allSquares) {
if (document.getElementById(allSquares).innerHTML != "") {
alert("Choose another square");
}
else {
if (cp1 == 1) {
document.getElementById(allSquares).innerHTML = "X";
cp1 = 2;
}
else {
document.getElementById(allSquares).innerHTML = "O";
cp1 = 1;
}
}
checkEmpty();
}
function checkEmpty() {
var checkForEmpty = false;
for (var i = false; i != true;)
</script>
</body>
</html>
Try this:
var cp1 = 1;
function displayMarker(allSquares) {
if (document.getElementById(allSquares).innerHTML != "") {
alert("Choose another square");
}
else {
if (cp1 == 1) {
document.getElementById(allSquares).innerHTML = "X";
cp1 = 2;
}
else {
document.getElementById(allSquares).innerHTML = "O";
cp1 = 1;
}
}
if(checkEmpty()) alert ("Done");
}
function checkEmpty() {
var allFilled = true;
var elements = document.getElementsByTagName("td");
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerHTML.length < 1) allFilled = false;
}
return allFilled;
}
It iterates over all <td> and checks their content length. If it is < 1, it'll set allEmpty = false. You could directly return false and true without the need for an additional variable, though I thought this might be easier to understand. Have fun!
I took some time and improved your code. Here is my result:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tic Tac Toe</title>
<style>
td {
border: 1px solid black;
height: 250px;
width: 250px;
font-family: sans-serif;
font-size: 150pt;
text-transform: uppercase;
}
</style>
</head>
<body>
<table>
<tr>
<td align="center" class="square" onclick="setMarker(0);"></td>
<td align="center" class="square" onclick="setMarker(1);"></td>
<td align="center" class="square" onclick="setMarker(2);"></td>
</tr>
<tr>
<td align="center" class="square" onclick="setMarker(3);"></td>
<td align="center" class="square" onclick="setMarker(4);"></td>
<td align="center" class="square" onclick="setMarker(5);"></td>
</tr>
<tr>
<td align="center" class="square" onclick="setMarker(6);"></td>
<td align="center" class="square" onclick="setMarker(7);"></td>
<td align="center" class="square" onclick="setMarker(8);"></td>
</tr>
</table>
<script>
var currentPlayer = true; // Only 2 Players, so boolean will do
var fields = document.getElementsByClassName ("square"); // Get all fields
function setMarker (fieldIndex) {
// Grab the clicked field by it's index
var clickedField = fields[fieldIndex];
// Does the fields textContent have a length? -> It has a value
if (clickedField.textContent.length > 0) {
alert ("Choose another square");
return;
}
// Decide based on the currentPlayer value if O or X is set. This construct is called ternary operator
clickedField.textContent = (currentPlayer) ? "O" : "X";
// Switch the boolean
currentPlayer = !currentPlayer;
// Check the fields
if(allFieldsSet ()) alert ("Game is done");
}
function allFieldsSet () {
// Iterate through fields, return false if we find an empty value
for (var i = 0; i < fields.length; i++) if (fields[i].textContent.length == 0) return false;
// Not returned yet, therefore we did not find an empty value -> return true
return true;
}
</script>
</body>
</html>

After setInterval( ) on click function will not work...Variable no longer increments

The code works for the most part.
Whenever the interval is set to refresh the game card, the onclick functions no longer work and the variable no longer increments.
What am I missing here?
You Can comment out the line with the setInterval() to see the desired outcome. It should refresh every second keeping the variable score and incrementing whenever someone clicks on the images. Thanks!
// var btn = document.getElementById('btn');
//btn.addEventListener('click', UpdateTable);
// Set the max length and Width
var maxWidth = 4;
var maxLength = 6;
// Returns a random number
function CreateRandom() {
return Math.floor(Math.random() * 2 + 1);
}
//function to create an image
function CreateGopher() {
var randomNumber = CreateRandom();
var image = "Sup";
if (randomNumber == 1) {
image = "<img src='gopher.jpg' class='gopher' height='100' width='100'>";
} else if (randomNumber == 2) {
image = "<img src='lettuce.jpg' class='lettuce' height='100' width='100'>";
}
return image;
}
//create table
function UpdateTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
function newTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
//Use The function update table
UpdateTable();
setTimeout(function() {
alert("Your Score is " + score)
}, 15000);
setInterval(UpdateTable, 1000);
var score = 0;
$(".lettuce").click(function() {
//alert( "You Clicked on the lettuce" );
score -= 5;
document.getElementById("scoreOut").innerHTML = score;
});
$(".gopher").click(function() {
//alert( "You Clicked on the lettuce" );
score += 5;
document.getElementById("scoreOut").innerHTML = score;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<center>
<div id="container">
<div id="header">
<h1>Welcome</h1>
<div id="scoreOut"></div>
</div>
<div id="content">
<table id="gameCard">
<tbody>
<tr>
<td id="cell00"> </td>
<td id="cell01"> </td>
<td id="cell02"> </td>
<td id="cell03"> </td>
</tr>
<tr>
<td id="cell10"> </td>
<td id="cell11"> </td>
<td id="cell12"> </td>
<td id="cell13"> </td>
</tr>
<tr>
<td id="cell20"> </td>
<td id="cell21"> </td>
<td id="cell22"> </td>
<td id="cell23"> </td>
</tr>
<tr>
<td id="cell30"> </td>
<td id="cell31"> </td>
<td id="cell32"> </td>
<td id="cell33"> </td>
</tr>
<tr>
<td id="cell40"> </td>
<td id="cell41"> </td>
<td id="cell42"> </td>
<td id="cell43"> </td>
</tr>
<tr>
<td id="cell50"> </td>
<td id="cell51"> </td>
<td id="cell52"> </td>
<td id="cell53"> </td>
</tr>
</tbody>
</table>
</div>
</div>
<br>
//<input id="btn" type="button" value="Play The Game!!" />
</center>
Figured it out!
Needed to put my JQUERY on.click goodies in the actual main function, which I did not have in the first place, in with the other functions nested in it.
<!--
To change this template use Tools | Templates.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gopher Broke</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<style>
#gameCard td{
padding:0; margin:0;
}
#gameCard {
border-collapse: collapse;
cursor:url(finger2.png), pointer;
}
</style>
</head>
<body>
<center>
<div id="container">
<div id="header">
<h1>GOPHER BROKE</h1>
<center>You have 15 seconds to stop as many gophers as possible!</center>
<div id="scoreOut">Score:</div>
<FORM>
<INPUT TYPE="button" onClick="history.go(0)" VALUE="Refresh">
</FORM>
</div>
<div id="content">
<table id="gameCard">
<tbody>
<tr>
<td id="cell00"> </td>
<td id="cell01"> </td>
<td id="cell02"> </td>
<td id="cell03"> </td>
</tr>
<tr>
<td id="cell10"> </td>
<td id="cell11"> </td>
<td id="cell12"> </td>
<td id="cell13"> </td>
</tr>
<tr>
<td id="cell20"> </td>
<td id="cell21"> </td>
<td id="cell22"> </td>
<td id="cell23"> </td>
</tr>
<tr>
<td id="cell30"> </td>
<td id="cell31"> </td>
<td id="cell32"> </td>
<td id="cell33"> </td>
</tr>
<tr>
<td id="cell40"> </td>
<td id="cell41"> </td>
<td id="cell42"> </td>
<td id="cell43"> </td>
</tr>
<tr>
<td id="cell50"> </td>
<td id="cell51"> </td>
<td id="cell52"> </td>
<td id="cell53"> </td>
</tr>
</tbody>
</table>
</div>
</div>
<br>
<!--<input id="btn" type="button" value="Play The Game!!" />-->
</center>
<script>
var score = 0;
function game(){
// var btn = document.getElementById('btn');
//btn.addEventListener('click', UpdateTable);
// Set the max length and Width
var maxWidth = 4;
var maxLength = 6;
// Returns a random number
function CreateRandom() {
return Math.floor(Math.random() * 4 + 1);
}
//function to create an image
function CreateGopher() {
var randomNumber = CreateRandom();
var image = "Sup";
if(randomNumber == 1){
image = "<img src='gopher.jpg' class='gopher' height='50' width='50'>";
}
else if(randomNumber == 2){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
else if(randomNumber == 3){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
else if(randomNumber == 4){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
return image;
}
//create table
function UpdateTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
function newTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
//Use The function update table
UpdateTable();
$( ".lettuce" ).click(function() {
//alert( "You Clicked on the lettuce" );
score -= 5;
document.getElementById("scoreOut").innerHTML = "<h1>Score :" + score;
});
$( ".gopher" ).click(function() {
//alert( "You Clicked on the lettuce" );
score += 5;
document.getElementById("scoreOut").innerHTML = "<h1>Score :" + score;
});
}
game();
setInterval(game, 1000);
setTimeout(function ()
{alert("Your Score is " + score)
window.location.href = "startGame.html";
}, 16000);
</script>
</body>
</html>

How to control highlighted cell with arrow keys

I have HTML table
When I click on it's cell (not header) this cell is highlighted in red. the rest cells in the same row are highlighted in pink color.
I want to control this red cell using arrow keys.
Here is my HTML code:
<html>
<head>
<title>Table Highlight</title>
</head>
<style>
.highlighted{
color: white;
background-color: red;
}
tr.normal td {
color: black;
background-color: white;
}
.highlighted1 {
color: white;
background-color: pink;
}
</style>
<body onLoad="onLoad()" >
<table id="tbl" border="1">
<tr>
<td style="width:70">Id
<td style="width:70">Name
<td style="width:70">Year
<td style="width:70">Task
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
</table>
<script>
tbl = document.getElementById('tbl');
tbl2 = document.getElementById('tbl');
cnt = 0;
function onLoad() {
td = document.getElementsByTagName('td');
for(j=4;j<td.length;j++){
td[j].innerHTML = " ";
td[j].onclick = function(){highlight(this)}
td[j].onkeydown=function(){key_highlight(event)}
}
}
function key_highlight(oo) {
td = document.getElementsByTagName('td');
for(n=1;i<tbl2.rows;n++){
cnt=0;
/*
if(cnt > tbl2[i].cells.length) return;
highlight(tbl2[i]);
}*/
alert();
//if(oo.keyCode==39)
if(cnt>tbl2.rows[n].cells.length) return;
highlight(tbl2[n].cells);
cnt++;
}
}
function highlight(o) {
for (i=0; i<tbl.cells.length; i++){
tbl.cells[i].className="normal";
tbl.cells[i].parentNode.className="normal";
}
o.parentNode.className = (o.className == "highlighted1")?"normal":"highlighted1";;
o.className=(o.className == "highlighted")?"normal":"highlighted";
}
</script>
</body>
You need to check for keycode on keydown event for the document and apply "highlighted" class to respective td.
HTML :
<table id="tbl" border="1">
<tr>
<td style="width:70" class="highlighted">Id</td>
<td style="width:70">Name</td>
<td style="width:70">Year</td>
<td style="width:70">Task</td>
</tr>
<tr>
<td style="height:20"> 1</td>
<td style="height:20"> Bob</td>
<td style="height:20"> 1998</td>
<td style="height:20"> NA</td>
</tr>
<tr>
<td style="height:20">2</td>
<td style="height:20">Maz</td>
<td style="height:20">2000</td>
<td style="height:20">QA</td>
</tr>
<tr>
<td style="height:20">3</td>
<td style="height:20">Mary</td>
<td style="height:20">1999</td>
<td style="height:20">Code</td>
</tr>
</table>
Jquery code:
var active;
$(document).keydown(function(e){
active = $('td.highlighted').removeClass('highlighted');
var x = active.index();
var y = active.closest('tr').index();
if (e.keyCode == 37) {
x--;
}
if (e.keyCode == 38) {
y--;
}
if (e.keyCode == 39) {
x++
}
if (e.keyCode == 40) {
y++
}
active = $('tr').eq(y).find('td').eq(x).addClass('highlighted');
});
Refer to fiddle for live Demo
You have to keep track of cell position (cellX,cellY) both when you click and when you press a key. Add a global keypress handler (document.onkeydown = ) and increment or decrement cellX and cellY according to the keys pressed.
Chech the running fiddle:
http://jsfiddle.net/aehq9c6f/1/
tbl = document.getElementById('tbl');
tbl2 = document.getElementById('tbl');
var cellX=null;
var cellY=null;
document.onkeydown = keyPressed;
cnt = 0;
function onLoad() {
td = document.getElementsByTagName('td');
for(j=4;j<td.length;j++){
td[j].innerHTML = " ";
td[j].onclick = function(){highlight(this)}
td[j].onkeydown=function(){key_highlight(event)}
}
}
function keyPressed(e) {
var code;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
var KeyVal=getCharDesc(code);
var maxX=4;
var maxY=4;
if(KeyVal=="left") {
if(cellX===null) cellX=maxX;
if(cellY===null) cellY=maxY/2;
cellX--;
if(cellX<0) cellX=maxX-1;
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="right") {
if(cellX===null) cellX=-1;
if(cellY===null) cellY=maxY/2;
cellX++;
if(cellX>maxX-1) cellX=0;
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="up") {
if(cellX===null) cellX=maxX/2;
if(cellY===null) cellY=maxY;
cellY--;
if(cellY<1) cellY=maxY-1; // avoid top row
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="down") {
if(cellX===null) cellX=maxX/2;
if(cellY===null) cellY=0; // avoid top row
cellY++;
if(cellY>maxY-1) cellY=1; // avoid top row
highlight(tbl.rows[cellY].cells[cellX]);
}
}
function getCharDesc(char_code) {
switch(char_code) {
case 37:return "left";
case 38:return "up";
case 39:return "right";
case 40:return "down";
}
}
function highlight(o) {
for (var i = 0, row; row = tbl.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
row.cells[j].className="normal";
row.cells[j].parentNode.className="normal";
if(row.cells[j]===o) {
cellX=j;
cellY=i;
// alert(cellX+", "+cellY);
}
}
}
o.parentNode.className = (o.className == "highlighted1")?"normal":"highlighted1";;
o.className=(o.className == "highlighted")?"normal":"highlighted";
}
The extra tests like
if(cellX===null) ...
are to allow first keypress if nothing is selected (cellX and cellY are null), if you hit left, cursor will start from right, etc.. (window must have focus so first click window to test).
I changed tbl.cells[i] to tbl.rows[i].cells[j] because on my setup (Firefox) table.cells[..] was not defined

Categories

Resources