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 = ''
}
});
Related
<!DOCTYPE html>
<html <head>
<meta charset="utf-8">
<title>Credit Card Number Validator</title>
<style>
<!-- .title {
font-family: "Trebuchet MS";
font-size: 30px;
font-style: oblique;
color: #006600;
text-align: center;
}
body {
background-color: #FFFFE8;
font-family: Arial, Helvetica, sans-serif;
}
table {
margin: auto;
width: 600px;
}
.right {
text-align: right;
}
.center {
text-align: center;
}
#id {
width: 175px;
}
-->
</style>
</head>
<body>
<p class="title">Validate a credit card number </p>
<form name="form1" id="form1" method="post" action="">
<table>
<tr>
<td width="219" class="right">Enter the credit card number:</td>
<td width="168" class="center"><input name="textfield" type="text" id="card"></td>
<td width="196" id="output"> </td>
</tr>
<tr>
<td height="30"> </td>
<td class="center"><input type="button" id="button" value="Test the Card Number!"></td>
<td> </td>
</tr>
</table>
</form>
<script>
document.getElementById("button").addEventListener('click', credit, false);
function credit() {
data = document.getElementById("card").value;
if (data) {
cardnum = data.replace(/[^0-9]/, "");
} else {
alert('Please enter a number to test.');
}
if (cardnum.length == 16 && cardnum.charAt(0) == "5" && cardnum.charAt(1) != "0" && cardnum.charAt(12) == "7") {
donecard = +cardnum.substr(0, 3) + " ";
document.getElementById("card").innerHTML = donecard;
document.getElementById("output").innerHTML = "valid";
} else {
document.getElementById("output").innerHTML = "invalid";
}
}
</script>
</body>
</html>
I'm trying to implement the Luhn algorithm to my code, so that it works together.
My first block works well it validates numbers correctly based off the code. This block works correctly. I want to implement the second part to it, which is the luhn algorithim with a loop or loops. What would be the best way to do this.
Something like this might work. Typed from my phone so probably has typos.
let sum = 0;
let len = cardnum.length;
for(let i=0; i = len; i++) {
let foo = cardnum.charAt(len-i)
if(i % 2 ) {
foo = foo * 2;
foo = (foo) > 9) ? foo-9 : foo;
sum = sum + foo;
} else {
sum = sum + foo
}
if( (sum * 9) % 10 === 0) {
console.log(‘valid’)
}
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.
i have a html table that displays student name and the number of leaves he has taken.how do i filter giving a constraint on the no of leaves and display it
,like if enter 5 in the text box,students with leave of 5 or more should be filtered and displayed.
the code i have now display the records with the entered value
function myFunction1() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput1");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[6];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
A jQuery version
var filter = $('#myInput1').val.toUpperCase();
$("#myTable tr td:eq(6)").each( function() {
var str = $(this).html().toUpperCase()
if( str.indexOf(filter) > -1)
$(this).parent('tr').css('display','')
else
$(this).parent('tr').css('display','none')
})
quick knock-together that does what you're looking for, from what I can understand. I have also used the same filter function to allow me to screen by name or by student-year. It's a flexible filter routine, wish I'd taken the time to avoid hard-wiring the handling of strings vs numbers, but for your purposes, that'd be overkill, I think.
A strange gotcha with table rows: you can't simply display="none" and display="block" them, it garbles the table structure. That's why it's display="none and display="" below. A few sources pointed that out, and I'm glad they did. I was beating my head on that wall for a while...
Best of luck!
// Store all the inputs...
var filterByName = document.getElementById("filter-by-name");
var filterByYear = document.getElementById("filter-by-year");
var filterByLeaves = document.getElementById("filter-by-leaves");
// And store the table itself.
var studentInfoTable = document.getElementsByClassName("student-info")[0];
// these functions will be called in the event listeners.
// By doing this, I only have a single filter function.
function byName() {
var filterString = filterByName.value;
filterBy("name", filterString);
};
function byYear() {
var filterString = filterByYear.value;
filterBy("year", filterString);
};
function byLeaves() {
var filterString = filterByLeaves.value;
filterBy("leaves", filterString);
};
/**
* The filter function itself, accepts the field to filter
* by and the string to use as the filter data.
* In essence, we take each row of the body, find the td
* to filter by, compare that with the filter data itself.
* There are two types of compare: either text or numeric.
*
**/
function filterBy(filter, filterString) {
var selector = ".student-" + filter;
var rows = studentInfoTable.querySelectorAll("tbody tr");
for (var i = 0; i < rows.length; i++) {
var filterEl = rows[i].querySelector(selector);
switch(filter) {
case "name":
if (filterEl.textContent.indexOf(filterString) == -1) {
rows[i].style.display = "none";
} else {
rows[i].style.display = "";
};
break;
case "year":
case "leaves":
if (parseInt(filterEl.textContent) >= parseInt(filterString) || filterString.length == 0) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
};
break;
}
}
};
// The event listeners for each input.
filterByName.addEventListener("keyup", byName);
filterByYear.addEventListener("keyup", byYear);
filterByLeaves.addEventListener("keyup", byLeaves);
.student-info {
font-family: Arial, sans-serif;
width: 100%;
table-layout: fixed;
}
thead {
font-weight: bold;
}
label {
display: block;
}
.student-name {
width: 40%;
}
.student-id,
.student-year,
.student-leaves {
width: 20%;
text-align: center;
}
<table class="student-info">
<thead>
<td class="student-name">Name</td>
<td class="student-id">S. Id</td>
<td class="student-year">Year</td>
<td class="student-leaves">Leaves</td>
</thead>
<tbody>
<tr>
<td class="student-name">Abraham Abas</td>
<td class="student-id">00141</td>
<td class="student-year">2018</td>
<td class="student-leaves">4</td>
</tr>
<tr>
<td class="student-name">Billy Bragg</td>
<td class="student-id">00143</td>
<td class="student-year">2018</td>
<td class="student-leaves">7</td>
</tr>
<tr>
<td class="student-name">Conor Chace</td>
<td class="student-id">00147</td>
<td class="student-year">2019</td>
<td class="student-leaves">5</td>
</tr>
<tr>
<td class="student-name">Daniel Daye</td>
<td class="student-id">00150</td>
<td class="student-year">2019</td>
<td class="student-leaves">0</td>
</tr>
<tr>
<td class="student-name">Edward Eppington</td>
<td class="student-id">00151</td>
<td class="student-year">2018</td>
<td class="student-leaves">6</td>
</tr>
<tr>
<td class="student-name">Frank Ford</td>
<td class="student-id">00153</td>
<td class="student-year">2020</td>
<td class="student-leaves">9</td>
</tr>
</tbody>
</table>
<div class="student-filter">
<h2>
Filter by...
</h2>
<label>Name:
<input type="text" id="filter-by-name">
</label>
<label>Year:
<input type="text" id="filter-by-year">
</label>
<label>Leaves:
<input type="text" id="filter-by-leaves">
</label>
</div>
Search Textbox:-
<label>Search:<input class="form-control input-sm" placeholder="" aria-controls="DataTables_Table_0" type="search" id="txtSearch" onkeyup="filter(this);"></label>
Script:-
function filter(element) {
var value = $(element).val();
$("#DataTables_Table_1 tr").each(function () {
if ($(this).text().search(value) > -1) {
$(this).show();
}
else {
$(this).hide();
}
});
}
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>
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