1

I'm trying to create a tic-tac-toe game using HTML/CSS/Javascript/jquery. I have a reset button that clears the contents of the grid. After pressing the reset button, the grid's contents gets cleared but I cannot click on my grid to pick my spot again. My reset button has the following code:

 $('#reset').click(function(){
   $('.cells').empty();
     //board_make();
 });

My grid/board was created using the code below. Basically it creates elements for each cell in the grid with each having a class of "cells".

function board_make(){
  for (var i = 0; i < 3; i ++){
    array[i] = new Array(3);
    for (var j = 0; j < 3; j ++){
      array[i][j] = "A" ;
      if(j == 2){
        $('.board').append("<div class='cells'><p class='hidden'>"+i.toString()+j.toString()+"</div></br></br></br>");
      }
      else{
      $('.board').append("<div class='cells'><p class='hidden'>"+i.toString()+j.toString()+"</div>");
      }
    }
  }
}

Finally, this is the code that gets executed whenever a cell in the grid is clicked on:

$('.cells').click(function(){
    if ($(this).text() != symbol){
      var a = parseInt($(this).text()[0],10);
      var b = parseInt($(this).text()[1],10);
      array[a][b] = symbol;
      $(this).html("<p class='shown'>"+symbol+"</p>");
    }
    else{
      alert("Spot taken. Pick another spot.");
    }
    if ((winner_found === false) && (hor_match() || ver_match() || diag_match())){
        alert("Match found!");
        winner_found = true;
    }  
 });

Here's the link to the work-in-progress along with the codes: http://jsbin.com/inazog/6/edit.

dexx1220
  • 91
  • 8
  • possible duplicate of [Event delegation in jQuery, how to do it?](http://stackoverflow.com/questions/12230057/event-delegation-in-jquery-how-to-do-it) – Shmiddty Dec 26 '12 at 20:01

4 Answers4

2

The problem is that you are using hidden text to indicate the row/col of the cell, but you remove the hidden text when you empty the cells.

"<div class='cells'><p class='hidden'>"+i.toString()+j.toString()+"</div>"

var a = parseInt($(this).text()[0],10);  // $(this).text() is "" after you clear the cells.
var b = parseInt($(this).text()[1],10);

See here for a fixed version of your code: http://jsbin.com/inazog/13/edit

Shmiddty
  • 13,349
  • 1
  • 32
  • 52
  • Thanks for the explanations everyone! Thanks Shmiddty for providing a fixed version. Happy holidays! – dexx1220 Dec 26 '12 at 20:40
1

edit — what's below isn't the problem. The problem appears to be that when clearing out the cells, you're clearing out the index values stashed in them. That is, you're removing the hidden <p> tags.

Instead of sticking the index in there, use the jQuery .data() mechanism:

var cell = ${'<div/>', {'class': 'cells'});
cell.data('x-index', i).data('y-index', j);
$('.board').append(cell);

Then you can get the index value of the cell without having to preserve the hidden elements.


Not the problem, but not really a bad idea:

Instead of

$('.cells').click(function(){

set up the event handler like this:

$('body').on('click', '.cells', function() { ...

When you empty out the container, all the elements are lost, and with them go the event handlers. By setting up the handler on an outer element that doesn't get nuked, the handler remains in effect after the grid is rebuilt.

If you wanted to, you could also put the event handler on the ".board" container:

$('.board').on('click', '.cells', function() { ...
Pointy
  • 371,531
  • 55
  • 528
  • 584
1

There are a lot of problems or potential problems here.

  • First of all, don’t bother defining your arrays’ dimensions beforehand, and use array literals instead of new Array. JavaScript mostly ignores that, and it can lead to strange bugs.
  • Next, use the DOM! Writing HTML over everything is just asking for event handlers to be lost.
  • Use data instead of parsing the nodes' text content. Or just use your array.
  • You’re not actually clearing the array when resetting. This could be because board_make() adds everything again; I don’t know. It would be better to actually remove the entire thing, and have board_make() make it all again. May as well add the event handlers in there, too, and keep everything nice and contained.
  • </br> isn’t valid HTML.

So, with that in mind, I changed some things and now it’s not really the same... :( But you get the idea, right?

Ry-
  • 199,309
  • 51
  • 404
  • 420
  • Thanks for the link. I'm still fairly new to programming so some parts of the createBoard() function you wrote are foreign to me, but I'll definitely spend time learning it. – dexx1220 Dec 26 '12 at 20:57
0
  1. Change: $('.cells').click(function() to $('.board').on('click', '.cells', function() so that the click event is alive on re-rendering.

  2. Change $('.cells').empty(); to $('.board').empty(); and re-render the board:

    board_make();

JSBin

JimmyRare
  • 3,694
  • 1
  • 18
  • 23