I am currently working on developing a Sudoku game using AngularJS. My goal is to capture the ng-keypress event even when clicking outside of the div on the page. An example of this behavior can be seen at . If you select a cell and then click anywhere else on the page, you can still change the number in the selected cell by clicking on any number. How can I implement this functionality?
Here's an excerpt of the HTML code:
<table class="sudoku-board" ng-init="getSudoku()" id="sudoku"
ng-class="{'paused': visible}">
<tbody>
<tr class="sudoku-row" ng-repeat="sudoku in sudokuGrid track by $index"
ng-init="row = $index">
<td class="sudoku-col sudoku-cell" ng-repeat="number in sudoku track by $index"
ng-init="col = $index" ng-class="{'highlight': colSelected === col || isHighlight(row, col) || rowSelected === row,
'highlight-number':getValue === number.substring(0, 1), 'selected':isSelected === ((row*10) + col), 'paused': visible}"
ng-click="selectedCell(row, col)"
ng-keydown="insertNum($event, row, col);" tabindex="1">
<span class="cell-value"
ng-class="{'empty': number === null || number.charAt(number.length-1) === '!', 'default': number !== null, 'paused': visible}"
ng-bind="number.substring(0, 1)"></span>
</td>
</tr>
</tbody>
</table>
The function triggered on ng-keydown is as follows:
// handle inserted value
$scope.insertNum = function (e, row, col, number) {
console.log("Number: " + number);
$scope.selectedCol = col; // get selected column
$scope.selectedRow = row; // get selected row
console.log(e);
if (e !== undefined) {
var keyCode = e.keyCode || e.charCode; // assign key & char code
if ((keyCode < 49 || ((keyCode > 57 && keyCode < 97) || keyCode > 105)) && (keyCode !== 8 && keyCode !== 46))
return false; // return false if clicked button/event is not a number or delete/backspace button
if (e.currentTarget.children[0].classList[2] === 'empty') // check if clicked cell is empty
if (keyCode === 8 || keyCode === 46) { // remove current value if delete/backspace is clicked
e.currentTarget.children[0].innerHTML = null;
$scope.sudokuGrid[row][col] = null;
$(e.target).removeClass("incorrect");
$(e.target).removeClass("correct");
$scope.handleErrorClass();
$scope.getValue = false;
}
else { // insert number in cell when number is clicked
e.currentTarget.children[0].innerHTML = e.key;
$scope.sudokuGrid[row][col] = e.key + "!";
$scope.checkCurrentNumber(row, col);
$scope.getCurrentNumber(row, col);
// add correct class if inserted number is correct
if (e.key === $scope.sudokuGridSolved[row][col]) {
console.log("Correct");
$(e.target).removeClass("incorrect");
$(e.target).addClass("correct");
}
// add incorrect class if inserted number is not correct
else {
console.log("Incorrect");
$(e.target).removeClass("correct");
$(e.target).addClass("incorrect");
}
}
}
else {
if (number !== null && $("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ") span").hasClass("empty")) {
$("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ") span").html(number);
$scope.sudokuGrid[row][col] = number + "!";
$scope.checkCurrentNumber(row, col);
$scope.getCurrentNumber(row, col);
// add correct class if inserted number is correct
if ($scope.getValue === $scope.sudokuGridSolved[row][col]) {
console.log("Correct");
$("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ")").removeClass("incorrect");
$("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ")").addClass("correct");
}
// add incorrect class if inserted number is not correct
else {
console.log("Incorrect!");
$("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ")").removeClass("correct");
$("tr:eq(" + $scope.selectedRow + ") td:eq(" + $scope.selectedCol + ")").addClass("incorrect");
}
}
}
$scope.checkForIdenticalValues();
}