I am currently trying to learn about backtracking Algorithms and have been working on a Sudoku game. I understand the basic working of the algorithm and have written a Sudoku solver using it.
My current problem is related to removing a set amount of numbers from a completed Sudoku grid to create a valid Sudoku with a unique solution.
I have checked similar questions on here but have found no answers.
Here is an example of a solved Sudoku grid:
solvedSudokuGrid =
[["8","6","1","3","4","2","9","5","7"],
["2","5","3","8","7","9","4","6","1"],
["4","9","7","6","5","1","2","3","8"],
["6","7","2","5","1","8","3","9","4"],
["9","1","4","7","2","3","6","8","5"],
["5","3","8","4","9","6","7","1","2"],
["3","4","6","2","8","5","1","7","9"],
["7","8","9","1","3","4","5","2","6"],
["1","2","5","9","6","7","8","4","3"]];
Here is the function to remove a set amount of numbers from the grid:
function removeNrs(grid, nrsToBeRemoved) {
//check if enough numbers have been removed
if (nrsToBeRemoved <= 0) {
return true;
}
//find the next random full cell and set the grid to "" on that cell to remove a number
var nextNr = shuffle(findFullCells(grid))[0];
var row = nextNr[0];
var column = nextNr[1];
var value = grid[row][column];
grid[row][column] = "";
nrsToBeRemoved--;
//check if the sudoku grid has only 1 solution if yes start recursion
if (countAllSolutions(grid) < 2){
if(removeNrs(grid, nrsToBeRemoved)){
return grid;
}
}
//if the sudoku grid has more than 1 possible solution return the grid to the previous state and backtrack
grid[row][column] = value;
return false;
}
Here is the problem: If I enter a low amount of numbers to be removed the function works.
ex:
removeNrs(solvedSudokuGrid, 5); //returns a valid grid
If I enter a higher amount of numbers to be removed the function simply returns false.
ex:
removeNrs(solvedSudokuGrid, 50); //returns false
From the basic debugging that I have tried I can see that the function works as long as it does not have to backtrack. If the function has to backtrack it seems to return all the way to the beginning and finish with the original grid before returning false.
Any help, explenations or things to read are much appreciated.
Edit:
https://jsfiddle.net/mg57u0mv/
Here is the complete code but some of the names of functions and variables have been changed to fit better with the whole code.
function createTable() {
var tbl = document.createElement("table");
var tbdy = document.createElement("tbody");
for (var row = 0; row < 9; row++) {
var tr = document.createElement("tr");
for (var column = 0; column < 9; column++) {
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "text";
input.id = "r"+row+"c"+column;
input.className = "grid-inputs grid-inputs-row-" + row;
//input.placeholder = "[" + row + " , " + column + "]";
//input.placeholder = input.id;
if ((row+1) % 3 === 0) {
td.style.borderBottom = "3px solid black";
}
if ((column+1) % 3 === 0) {
td.style.borderRight = "3px solid black";
}
tr.appendChild(td);
td.appendChild(input);
}
tbdy.appendChild(tr);
}
tbl.appendChild(tbdy);
document.body.appendChild(tbl);
}
function createButton(text, func) {
var button = document.createElement("button");
var t = document.createTextNode(text);
button.onclick = func;
button.appendChild(t);
document.body.appendChild(button);
}
function shuffle(array) {
var counter = array.length;
var temp, index;
while (counter) {
index = Math.floor(Math.random() * counter);
counter--;
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
}
function retrieveGrid() {
var result = [];
var rowContents = [];
for (var row = 0; row < 9; row++) {
for (var column = 0; column < 9; column++) {
rowContents.push(document.getElementsByClassName("grid-inputs-row-"+row)[column].value);
}
result.push(rowContents);
rowContents = [];
}
return result;
}
function printGrid(grid) {
for (var row = 0; row < 9; row++) {
for (var column = 0; column < 9; column++) {
document.getElementsByClassName("grid-inputs-row-"+row)[column].value = grid[row][column];
}
}
}
function checkRowColumnBlock(grid, row, column, value) {
//create row, column and block lists to be checked for doubles
var rowList = grid[row];
var columnList = [];
for (var columnCounter = 0; columnCounter < 9; columnCounter++) {
columnList.push(grid[columnCounter][column]);
}
var blockList = [];
for (var startRow = Math.floor(row/3) * 3, endRow = startRow + 3; startRow < endRow; startRow++) {
for (var startColumn = Math.floor(column/3) * 3, endColumn = startColumn + 3; startColumn < endColumn; startColumn++) {
blockList.push(grid[startRow][startColumn]);
}
}
//check row, column and block list for value
if (rowList.indexOf(value.toString()) === -1 &&
columnList.indexOf(value.toString()) === -1 &&
blockList.indexOf(value.toString()) === -1) {
return true;
} else {
return false;
}
}
function checkGrid(grid) {
for (var row = 0; row < 9; row++) {
for (var column = 0; column < 9; column++) {
if (grid[row][column] !== "") {
var value = grid[row][column];
grid[row][column] = "";
if (!checkRowColumnBlock(grid, row, column, value)) {
console.log("Invalid Grid");
return false;
}
grid[row][column] = value;
}
}
}
console.log("Valid Grid");
return true;
}
function findEmptyCells(grid) {
var result = [];
for (var row = 0; row < 9; row++){
for (var column = 0; column < 9; column++) {
if (grid[row][column] === "") {
result.push([row , column]);
}
}
}
if (result.length == 0) {
result = false;
}
return result;
}
function sortPossibilties(grid) {
var result = [];
var listOfEmptyCells = findEmptyCells(grid);
if (listOfEmptyCells === false) {
return false;
}
var listOfPossibilities = findPossibilitiesForGrid(grid);
var counter = listOfEmptyCells.length;
for (var cell = 0; cell < counter; cell++) {
result.push({"cell": listOfEmptyCells[cell], "possibilities": listOfPossibilities[cell]});
}
result.sort(function (first, second) {
return first.possibilities.length - second.possibilities.length;
});
return result;
}
function findNextEmptyCell(grid) {
var sortedEmptyCells = sortPossibilties(grid);
if (sortedEmptyCells === false) {
return false;
}
return sortedEmptyCells[0];
}
function findFullCells(grid) {
var result = [];
for (var row = 0; row < 9; row++){
for (var column = 0; column < 9; column++) {
if (grid[row][column] !== "") {
result.push([row , column]);
}
}
}
if (result.length == 0) {
result = false;
}
return result;
}
function findRandomFullCell(listOfFullCells) {
if (listOfFullCells === false) {
return false;
}
var result = listOfFullCells[Math.floor(Math.random() * listOfFullCells.length)];
return result;
}
function createEmptyGrid() {
//create grid 9x9 fill with blankspace
var grid = [];
for (var gridCounter = 0; gridCounter < 9; gridCounter++) {
grid.push(new Array(9).fill(""));
}
return grid;
}
function createIncRandomGrid(numberOfRandomCells) {
var grid = createEmptyGrid();
for (var counter = 0; counter < numberOfRandomCells; counter++) {
grid[Math.floor(Math.random() * 9)][Math.floor(Math.random() * 9)] =
Math.floor(Math.random() * 9 + 1).toString();
}
return grid;
}
function createCorRandomGrid(numberOfRandomCells) {
var grid;
do {grid = createIncRandomGrid(numberOfRandomCells);}
while (checkGrid(grid) === false);
return grid;
}
function findPossibilitiesForCell(grid, row, column) {
var possibilities = [];
for (var value = 1; value < 10; value++) {
if (checkRowColumnBlock(grid, row, column, value)) {
possibilities.push(value.toString());
}
}
return possibilities;
}
function findPossibilitiesForGrid(grid) {
var result = [];
var listOfEmptyCells = findEmptyCells(grid);
var amountOfEmptyCells = listOfEmptyCells.length;
for (var cell = 0; cell < amountOfEmptyCells; cell++) {
var row = listOfEmptyCells[cell][0];
var column = listOfEmptyCells[cell][1];
result.push(findPossibilitiesForCell(grid, row, column));
}
return result;
}
function solveSudoku(grid) {
var emptyCell = findNextEmptyCell(grid);
if (emptyCell === false) {
return true;
}
var row = emptyCell.cell[0];
var column = emptyCell.cell[1];
var valueList = shuffle(emptyCell.possibilities);
var valueListLength = valueList.length;
for (var valueIndex = 0; valueIndex < valueListLength; valueIndex++) {
if (checkRowColumnBlock(grid, row, column, valueList[valueIndex])) {
grid[row][column] = valueList[valueIndex].toString();
if (solveSudoku(grid)) {
return grid;
}
grid[row][column] = "";
}
}
return false;
}
function countAllSolutions(grid) {
var nrOfSolutions = 1;
function solveAll(grid) {
var emptyCell = findNextEmptyCell(grid);
if (emptyCell === false || nrOfSolutions > 1) {
return true;
}
var row = emptyCell.cell[0];
var column = emptyCell.cell[1];
var valueList = shuffle(emptyCell.possibilities);
var valueListLength = valueList.length;
for (var valueIndex = 0; valueIndex < valueListLength; valueIndex++) {
if (checkRowColumnBlock(grid, row, column, valueList[valueIndex])) {
grid[row][column] = valueList[valueIndex].toString();
if (solveAll(grid)) {
nrOfSolutions++;
}
grid[row][column] = "";
}
}
return false;
}
solveAll(grid);
return nrOfSolutions-1;
}
function findPossibilitiesForFullCell(grid, row, column) {
var possibilities = [];
var originalValue = grid[row][column];
grid[row][column] = "";
for (var value = 1; value < 10; value++) {
if (checkRowColumnBlock(grid, row, column, value)) {
possibilities.push(value.toString());
}
}
grid[row][column] = originalValue;
return possibilities;
}
function findPossibilitiesForFullGrid(grid) {
var result = [];
var listOfFullCells = findFullCells(grid);
var amountOfFullCells = listOfFullCells.length;
for (var cell = 0; cell < amountOfFullCells; cell++) {
var row = listOfFullCells[cell][0];
var column = listOfFullCells[cell][1];
result.push(findPossibilitiesForFullCell(grid, row, column));
}
return result;
}
function sortFullCells(grid) {
var result = [];
var listOfFullCells = findFullCells(grid);
if (listOfFullCells === false) {
return false;
}
var listOfPossibilities = findPossibilitiesForFullGrid(grid);
var counter = listOfFullCells.length;
for (var cell = 0; cell < counter; cell++) {
result.push({"cell": listOfFullCells[cell], "possibilities": listOfPossibilities[cell]});
}
result.sort(function (first, second) {
return first.possibilities.length - second.possibilities.length;
});
return result;
}
function findNextFullCells(grid) {
var sortedFullCells = sortFullCells(grid);
if (sortedFullCells === false) {
return false;
}
var result = [];
result.push(sortedFullCells[0]);
for (var cell = 1, length = sortedFullCells.length; cell < length; cell++){
if(sortedFullCells[cell].possibilities.length === sortedFullCells[0].possibilities.length) {
result.push(sortedFullCells[cell]);
}
}
return result;
}
function removeCells(grid, cellsToBeRemoved) {
if (cellsToBeRemoved <= 0) {
return grid;
}
var nextCell = shuffle(findFullCells(grid))[0];
var row = nextCell[0];
var column = nextCell[1];
var value = grid[row][column];
grid[row][column] = "";
cellsToBeRemoved--;
if (countAllSolutions(grid) < 2) {
grid = removeCells(grid, cellsToBeRemoved);
return grid;
} else {
grid[row][column] = value;
grid = removeCells(grid, cellsToBeRemoved);
}
return grid;
}
createTable();
createButton("Solve Sudoku", function () {
console.time("Solved");
printGrid(solveSudoku(retrieveGrid()));
console.timeEnd("Solved");
});
createButton("Remove Cells", function () {
console.time("Removed");
printGrid(removeCells(retrieveGrid(),55));
console.timeEnd("Removed");
});
createButton("Count Solutions", function () {
console.time("Counting");
console.log(countAllSolutions(retrieveGrid()));
console.timeEnd("Counting");
});
createButton("Create Random Grid", function () {
printGrid(createIncRandomGrid(100));
});
createButton("Create Correct Random Grid", function () {
printGrid(createCorRandomGrid(17));
});
createButton("Check Grid", function () {
checkGrid(retrieveGrid());
});
createButton("Count Full Cells", function () {
console.log(findFullCells(retrieveGrid()).length);
});
createButton("Count Empty Cells", function () {
console.log(findEmptyCells(retrieveGrid()).length);
});
createButton("Sort Empty Cells", function () {
console.log(sortPossibilties(retrieveGrid()));
});
createButton("Sort Full Cells", function () {
console.log(sortFullCells(retrieveGrid()));
});
createButton("Reset Grid", function () {
printGrid(createEmptyGrid());
});
I haven't actually tested it but I did test a similar function.
Try this at the end, replacing your last eight lines:
if (countAllSolutions(grid) < 2) grid = removeNrs(grid, nrsToBeRemoved);
else grid[row][column] = value;
return grid;
I am working on an app development which will read through my mailbox and list all the unread e-mails in a HTML table on my web-app upon click of a button. Below is the code which I have made while researching through google which solves for the purpose.
<!DOCTYPE html>
<html>
<body>
<button onclick="groupFunction()">Click me</button>
<table id="tblContents">
<tr onclick="tableClickTest()">
<th>Sender</th>
<th>Sent_Date</th>
<th>Received_By</th>
<th>Received_Date</th>
<th>Subject</th>
</tr>
</table>
<script>
function RowSelection()
{
var table = document.getElementById("tblContents");
if (table != null) {
for (var i = 0; i < table.rows.length; i++) {
for (var j = 0; j < table.rows[i].cells.length; j++)
table.rows[i].cells[j].onclick = function () {
tableText(this);
};
}
}
}
function tableText(tableCell) {
alert(tableCell.innerHTML);
}
function PopulateTable()
{
var objOutlook = new ActiveXObject("Outlook.Application");
var session = objOutlook.Session;
//alert(session.Folders.Count)
for(var folderCount = 1;folderCount <= session.Folders.Count; folderCount++)
{
var folder = session.Folders.Item(folderCount);
//alert(folder.Name)
if(folder.Name.indexOf("Premanshu.Basak#genpact.com")>=0)
{
for(var subFolCount = 1; subFolCount <= folder.Folders.Count; subFolCount++)
{
var sampleFolder = folder.Folders.Item(subFolCount);
//alert(sampleFolder.Name)
if(sampleFolder.Name.indexOf("test1")>=0)
{
for(var itmCount = 1; itmCount <= sampleFolder.Items.Count; itmCount++)
{
var itm = sampleFolder.Items.Item(itmCount);
if(!itm.UnRead)
continue;
var sentBy = itm.SenderName;
var sentDate = itm.SentOn;
var receivedBy = itm.ReceivedByName;
var receivedDate = itm.ReceivedTime;
var subject = itm.ConversationTopic;
// var contents = itm.Body;
var tbl = document.getElementById("tblContents");
if(tbl)
{
var tr = tbl.insertRow(tbl.rows.length);
// tr.onclick(tableClickTest())
if(tbl.rows.length%2 != 0)
tr.className = "alt";
var tdsentBy = tr.insertCell(0);
var tdsentDate = tr.insertCell(1);
var tdreceivedBy = tr.insertCell(2);
var tdreceivedDate = tr.insertCell(3);
var tdsubject = tr.insertCell(4);
// var tdcontents = tr.insertCell(5);
tdsentBy.innerHTML = sentBy;
tdsentDate.innerHTML = sentDate;
tdreceivedBy.innerHTML = receivedBy;
tdreceivedDate.innerHTML = receivedDate;
tdsubject.innerHTML = subject;
// tdcontents.innerHTML = contents;
}
//itm.UnRead = false;
}
break;
}
}
break;
}
}
return;
}
function groupFunction()
{
PopulateTable()
RowSelection()
}
</script>
</body>
</html>
The thing that I am now looking for and is unable to do is how do I add a checkbox in the first column in each row. Also upon checking this checkbox the entire row should get highlighted so that I can perform specific task on all the selected items.
As far as I have understood your code, your first column's data is being set as:
tdsentBy.innerHTML = sentBy;
So in the same line, you can add textbox as a string as:
var cbox = "<div class='select-box'>
<input type='checkbox' name='selectBox' class='select-row'>
</div?>"
tdsentBy.innerHTML = cbox + sentBy;
In this way, a checkbox will always be available in first column of every row.
Now in RowSelection function, to bind event you can do something like:
var checkBox = table.rows[i].cells[j].querySelector(".select-row");
checkBox.addEventListener("click",function(evt){
});
I have a unique problem that I hope someone can help with. I have a page that pulls data from a controller with AJAX and presents it to this function to construct a table:
// make rows in table from json data
function makeTableRows() {
if (jsonTableData != null) {
tbl = null;
tbl = createTable('tableResults');
// constructHeader(tbl, 'left', jsonTableData[0]);
newHeader(tbl, 'left', jsonTableData[0]);
var totalItems = jsonTableData.length;
var topItem;
topItem = 0;
if ((lastItem + perpage) > totalItems) {
topItem = totalItems;
$(".btnNext").prop('disabled', true);
}
else {
topItem = lastItem + perpage;
}
for (var i = lastItem; i <= topItem - 1; i++) {
makeTableRow(tbl, jsonTableData[i], 'left', true, 'showTourDetails(' + jsonTableData[i]["TransactionID"] + ',' + i + ')', 0);
}
$("#divSearchResults").html(tbl);
makePagesLabel();
makeTableFooter(tbl);
}
}
the function inside the separate file is this:
function constructHeader(table, alignment, firstRow) {
if (firstRow != null) {
var thead = document.createElement('thead');
table.appendChild(thead);
var tr = document.createElement('tr');
for (var key in firstRow) {
var header = key.match(/[A-Z][a-z]*/g);
var newHeader = '';
for (var i = 0; i <= header.length - 1; i++) {
newHeader += header[i] + ' ';
}
var th = document.createElement('th');
var text = document.createTextNode(newHeader);
th.appendChild(text);
th.style.textAlign = alignment;
th.style.cursor = 'pointer';
th.setAttribute('title', "Sort by " + newHeader);
th.onclick = function () {
var rows = $(table).find('tbody').find('tr').toArray().sort(comparer($(this).index()));
this.asc = !this.asc;
if (!this.asc) {
rows = rows.reverse();
}
for (var j = 0; j < rows.length; j++) {
$(table).append(rows[j]);
}
$(table).find('tbody').find('tr:even').css("background-color", "#dae5f4");
$(table).find('tbody').find('tr:odd').css("background-color", "#b8d1f3");
};
tr.appendChild(th);
}
thead.appendChild(tr);
}
}
Basically the function creates a sort process for the header of each column. After the sort of the column, I want to reapply the zebra striping that is applied with the class of the table. If I don't try to reapply I end up with the striping all messed up. Now, the problem is that if I copy the function into the .cshtml page and give it the name of 'newheader', the re-striping works fine. It does not work in the separate JS file and I cannot figure out why. Anyone have any clues?
I'm learning phonegap by making a simple t-do app.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>To-dos</title>
</head>
<body onload='loadToDoList()'>
<input type='button' value='Add To-do' onclick='createNewToDo()'/>
<input type='button' value='Remove completed To-dos' onclick='removeCompletedTasks()'/>
<br/><br/>
<table id='dataTable' width='100%' border='1'>
</table>
<script src='js/index.js'></script>
</body>
</html>
index.js:
(function() {
var addTableRow, checkboxClicked, deleteAllRows, deleteSelectedRow, loadToDoList, saveToDoList, viewSelectedRow;
window.rowID = 0;
saveToDoList = function() {
var checkBoxState, chkbox, i, row, rows, table, textValue, textbox, todoArray, _i, _len;
todoArray = {};
checkBoxState = 0;
textValue = '';
table = document.getElementById('dataTable');
rows = table.rows;
if (rows.length > 0) {
i = 0;
for (_i = 0, _len = rows.length; _i < _len; _i++) {
row = rows[_i];
chkbox = rows.cells[0].childNodes[0];
if ((chkbox != null) && chkbox.checked === true) {
checkBoxState = 1;
} else {
checkBoxState = 0;
}
textbox = row.cells[1].childNodes[0];
textValue = textbox.value;
todoArray["row" + (i++)] = {
check: checkBoxState,
text: textValue
};
}
} else {
todoArray = null;
}
return window.localStorage.setItem('todoList', JSON.stringify(todoArray));
};
loadToDoList = function() {
var i, key, theList, val, _results;
theList = JSON.parse(window.localStorage.getItem('todoList'));
deleteAllRows();
if (theList !== null && theList !== 'null') {
i = 0;
_results = [];
for (key in theList) {
val = theList[key];
_results.push(addTableRow(theList["row" + (i++)], true));
}
return _results;
}
};
deleteAllRows = function() {
var i, rowCount, table, _i;
table = document.getElementById('dataTable');
rowCount = table.rows.count;
for (i = _i = 0; 0 <= rowCount ? _i < rowCount : _i > rowCount; i = 0 <= rowCount ? ++_i : --_i) {
table.deleteRow(i);
rowCount--;
i--;
}
return saveToDoList();
};
viewSelectedRow = function(todoTextField) {
return alert(todoTextField.value);
};
deleteSelectedRow = function(deleteButton) {
deleteButton.parentNode.parentNode.parentNode.removeChild();
return saveToDoList();
};
checkboxClicked = function() {
var chkbox, row, rows, table, textbox, _i, _len, _results;
table = document.getElementById('dataTable');
rows = table.rows;
_results = [];
for (_i = 0, _len = rows.length; _i < _len; _i++) {
row = rows[_i];
chkbox = row.cells[0].childNodes[0];
textbox = row.cells[1].childNodes[0];
if ((chkbox != null) && chkbox.checked === true && (textbox != null)) {
textbox.style.setProperty('text-decoration', 'line-through');
} else {
textbox.style.setProperty('text-decoration', 'none');
}
_results.push(saveToDoList());
}
return _results;
};
addTableRow = function(todoDictionary, appIsLoading) {
var cell1, cell2, element1, element2, row, rowCount, table;
rowID++;
table = document.getElementById('dataTable');
rowCount = table.rows.length;
row = table.insertRow(rowCount);
cell1 = row.insertCell(0);
element1 = document.createElement('input');
element1.type = 'checkbox';
element1.name = 'chkbox[]';
element1.checked = todoDictionary['check'];
element1.setAttribute('onclick', 'checkboxClicked()');
cell1.appendChild(element1);
cell2 = row.insertCell(1);
element2 = document.createElement('input');
element2.type = 'text';
element2.name = 'txtbox[]';
element2.size = 16;
element2.id = 'text' + rowID;
element2.value = todoDictionary['text'];
element2.setAttribute('onchange', 'saveToDoList()');
cell2.appendChild(element2);
checkboxClicked();
saveToDoList();
if (!appIsLoading) {
return alert('Task added successfully');
}
};
window.createNewToDo = function() {
var todo, todoDictionary;
todoDictionary = {};
todo = prompt('To-Do', '');
if (todo != null) {
if (todo === '') {
return alert('To-Do can\'t be empty');
} else {
todoDictionary = {
check: 0,
text: todo
};
return addTableRow(todoDictionary, false);
}
}
};
window.removeCompletedTasks = function() {
var chkbox, i, rowCount, table, _i;
table = document.getElementById('dataTable');
rowCount = table.rows.length;
for (i = _i = 0; 0 <= rows ? _i < rows : _i > rows; i = 0 <= rows ? ++_i : --_i) {
chkbox = table.rows[i].cells[0].childNodes[0];
if ((chkbox != null) && chkbox.checked === true) {
table.deleteRow(i);
i--;
rowCount--;
}
}
saveToDoList();
return alert('Completed tasks were removed');
};
}).call(this);
My createNewToDo function works fine, since I'm able to create new todos. But when I check a todo and click on the remove button, nothing happens. Why is my removeCompletedTasks function not being called?
Here is the provided code in JSFiddle. The primary reason that I can see for removeCompletedTasks failing is that rows is undefined. After that is fixed, the other errors are caused by the methods you have defined only being in scope inside of the outside function. Once it completes, they are gone and cannot be called.
Each of the methods need to have window. before them. Then the saveToDoList needs a little work. the table method doesn't work, just go directly for the rows. Once you have the row you want use that reference.
window.saveToDoList = function() {
var checkBoxState, chkbox, i, row, rows, textValue, textbox, todoArray, _i, _len;
todoArray = {};
checkBoxState = 0;
textValue = '';
rows = document.getElementById('dataTable').rows;
if (rows.length > 0) {
i = 0;
for (_i = 0, _len = rows.length; _i < _len; _i++) {
row = rows[_i];
chkbox = row.childNodes[0];
if ((chkbox != null) && chkbox.checked === true) {
checkBoxState = 1;
} else {
checkBoxState = 0;
}
textbox = row.childNodes[1];
textValue = textbox.value;
todoArray["row" + (i++)] = {
check: checkBoxState,
text: textValue
};
}
} else {
todoArray = null;
}
return window.localStorage.setItem('todoList', JSON.stringify(todoArray));
};
With that method working, now the removeCompletedTasks needs some fine tuning. The loop can be simplified to a simple for loop. Removing the row is done by getting it fresh each time, I know this is slower, but at least chrome returns a function for table the way it was. To get the checkbox, one more level of children needed peeling, and now it works.
window.removeCompletedTasks = function() {
var chkbox, i, rowCount, rows;
rows = document.getElementById('dataTable').rows;
rowCount = rows.length;
for (i = 0; i < rowCount; ++i) {
chkbox = rows[i].childNodes[0].childNodes[0];
if ((chkbox != null) && chkbox.checked === true) {
document.getElementById("dataTable").deleteRow(i);
--i;
--rowCount;
}
}
saveToDoList();
return alert('Completed tasks were removed');
};
Check out the new JSFiddle for the working example.
I am trying to create mine field game. "I am very new to Js".
What I have done so far:
var level = prompt("Choose Level: easy, medium, hard");
if (level === "easy") {
level = 3;
} else if (level === "medium") {
level = 6;
} else if (level === "hard") {
level = 9;
}
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
for (var i = 1; i <= 10; i++) {
var row = document.createElement("tr");
document.write("<br/>");
for (var x = 1; x <= 10; x++) {
var j = Math.floor(Math.random() * 12 + 1);
if (j < level) {
j = "mined";
} else {
j = "clear";
}
var cell = document.createElement("td");
var cellText = document.createTextNode(j + " ");
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
tbl.setAttribute("border", "2");
So I create here 2d table and enter 2 random values in rows and columns (mined or clear).
Where I am stuck is:
Check if td = mined it dies otherwise open the box(td) etc.
How do I assign value of td? I mean how can I check which value(mined/clear) there is in the td which is clicked?
Ps: Please don't write the whole code:) just show me the track please:)
Thnx for the answers!
Ok! I came this far.. But if I click on row it gives sometimes clear even if I click on mined row or vice versa!
// create the table
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
tbl.setAttribute('id','myTable');
var tblBody = document.createElement("tbody");
//Create 2d table with mined/clear
for(var i=1;i<=10;i++)
{
var row = document.createElement("tr");
document.write("<br/>" );
for(var x=1;x<=10;x++)
{
var j=Math.floor(Math.random()*12+1);
if(j<level)
{
j = "mined";
}
else{
j = "clear";
}
var cell = document.createElement("td");
var cellText = document.createTextNode(j + "");
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
tbl.setAttribute("border", "2");
//Check which row is clicked
window.onload = addRowHandlers;
function addRowHandlers() {
var table = document.getElementById("myTable");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var currentRow = table.rows[i];
var createClickHandler =
function(row)
{
return function() {
var cell = row.getElementsByTagName("td")[0];
var id = cell.innerHTML;
if(id === "mined")
{
alert("You died");
}else
{
alert("clear");
}
};
}
currentRow.onclick = createClickHandler(currentRow);
}
}
I think I do something wrong with giving the table id "myTable"..
Can you see it?
Thank you in advance!
So, the idea would be:
assign a click event to each td cell:
td.addEventListener('click', mycallback, false);
in the event handler (callback), check the content of the td:
function mycallback(e) { /*e.target is the td; check td.innerText;*/ }
Pedagogic resources:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td?redirectlocale=en-US&redirectslug=HTML%2FElement%2Ftd
https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener
JavaScript, getting value of a td with id name