Search code examples
javascriptjqueryangularjsangularjs-ng-repeattic-tac-toe

How to add content inside div with angular without using jquery


I'm trying to build a basic tic tac toe game in angular 1. When I click on a square I want to either add X or O depending on the turn. I cannot figure out how to do that. I can do it in jquery but I want to do it in angular.

<div class="squares-container" ng-repeat="square in squares">
  <div class="s" id="{{ $index + 1 }}" ng-click="move(square)", ng-bind="{{ $index + 1 }}"></div>
</div>

angular
.module('app')
.directive('ticTacToe', function(){
    return {
      restrict: 'E',
      templateUrl: 'tic-tac-toe.html',
      controller: controller

    };

    function controller($scope){
        function init() {
            let turn = 0;
            let currentPiece = 'X';

            $scope.squares = [1, 2, 3, 4, 5, 6, 7, 8, 9];
            $scope.move = function(id){
                currentPiece = turn % 2 === 0 ? 'X' : 'O';
                $scope.id = currentPiece;
                turn++;  
            };
        }
        init();
    }
})

Here's the code. https://plnkr.co/edit/UwHsltXVLFAVG6pHKKwO?p=preview


Solution

  • You can set your squares to objects and simply alter the properties of them.

    When you click on a square, pass it to your move function, find the index of it and change the piece property of that square.

    (function() {
    
      'use strict';
    
      angular.module('app', []);
    
    })();
    
    (function() {
    
      'use strict';
    
      angular.module('app').directive('ticTacToe', TicTacToeDirective);
    
      function TicTacToeDirective() {
    
        return {
          restrict: 'E',
          templateUrl: 'tic-tac-toe.html',
          controller: TicTacToeController,
          controllerAs: 'TicTacToeCtrl'
        };
    
      }
    
      TicTacToeController.$inject = [];
    
      function TicTacToeController() {
    
        // reference this to make it available in the view using the controller as syntax
        var vm = this;
    
        // expose our move function to the view
        vm.move = move;
    
        // we can even expose our newGame function to start a new game
        vm.newGame = newGame;
    
        // set our defaults - we will add turn to this controller so we can display it in the view 
        vm.turn = 0;
        var currentPiece = "X";
    
        // start a new game
        newGame();
    
        function move(square) {
    
          // get the index of the square passed in
          var index = vm.squares.indexOf(square);
    
          // set the squares piece property to the correct piece if it doesn't already have one set
    
          if (!vm.squares[index].piece) {
    
            vm.squares[index].piece = vm.turn % 2 === 0 ? 'X' : 'O';
    
            // increment the number of turns
            vm.turn++;
    
          }
    
        }
    
        function newGame() {
    
          // reset turn
          vm.turn = 0;
    
          // reset current piece
          currentPiece = "X";
    
          // setup our squares
          vm.squares = [{
              id: 1,
              piece: null
            }, {
              id: 2,
              piece: null
            },
            {
              id: 3,
              piece: null
            },
            {
              id: 4,
              piece: null
            },
            {
              id: 5,
              piece: null
            },
            {
              id: 6,
              piece: null
            },
            {
              id: 7,
              piece: null
            }, {
              id: 8,
              piece: null
            },
            {
              id: 9,
              piece: null
            }
          ];
        }
    
      }
    
    })();
    /* Styles go here */
    
    .container {
      background-color: #14bdac;
    }
    
    .s {
      border: 1px solid #000;
      width: 50px;
      height: 50px;
      float: left;
    }
    
    .divider {
      display: block;
      clear: both;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
    
    <div ng-app="app">
    
      <tic-tac-toe></tic-tac-toe>
    
      <script type="text/ng-template" id="tic-tac-toe.html">
    
        <button ng-click="TicTacToeCtrl.newGame()">New game</button> Turns taken: {{TicTacToeCtrl.turn}}
    
        <hr>
    
        <div class="squares-container" ng-repeat-start="square in TicTacToeCtrl.squares track by $index">
          <div class="s" id="{{::square.id}}" ng-click="TicTacToeCtrl.move(square)">
            {{::square.id}}
            <span class="checked">{{square.piece}}</span>
          </div>
        </div>
        <div ng-repeat-end class="divider" ng-if="!(square.id % 3)"></div>
    
      </script>
    
    </div>