简体   繁体   中英

How do I make empty cells editable in a Sudoku table in javascript?

I wrote a function that generates random numbers to an 2d array. With this function I could fill the cells of a sudoku table (built in HTML) with random numbers. But for some reason when I fill the random numbers to my HTML table (using.innerHTML) I cannot edit the empty cells. The empty cells are locked although I used inputs to build the table. Please Help me so I can make the empty cells editable. I tried to use the attribute contenteditable:"true" in the the td but the problem is that it also allows to delete the cells filled with the random numbers and doesn't restrict the text area to numbers only from 1-9.

Here is the JS part:

 let sudoku = [ [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], ]; window.onload = function () { generateSudoku(61); fillEmptySudoku(); }; function generateSudoku(displayedNumbers) { let numAdded = 0; while (numAdded < displayedNumbers) { let row = Math.floor(Math.random() * 9); let col = Math.floor(Math.random() * 9); let number = Math.floor(Math.random() * 9) + 1; if (sudoku[row][col] === null) { sudoku[row][col] = number; } else { numAdded++; } } return sudoku; } let table = document.getElementById("table"); //enter the matrix value into the html table function fillEmptySudoku() { for (let i = 0; i < table.rows.length; i++) { for (let j = 0; j < table.rows[i].cells.length; j++) { table.rows[i].cells[j].innerHTML = sudoku[i][j]; } } }
 Here is the HTML part: <table id="table"> <tr class="tr" id="row1"> <td class="td" id="cell1"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell2"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell3"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell4"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell5"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell6"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell7"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell8"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell9"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row2"> <td class="td" id="cell10"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell11"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell12"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell13"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell14"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell15"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell16"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell17"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell18"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row3"> <td class="td" id="cell19"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell20"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell21"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell22"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell23"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell24"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell25"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell26"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell27"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row4"> <td class="td" id="cell28"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell29"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell30"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell31"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell32"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell33"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell34"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell35"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell36"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row5"> <td class="td" id="cell37"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell38"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell39"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell40"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell41"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell42"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell43"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell44"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell45"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row6"> <td class="td" id="cell46"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell47"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell48"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell49"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell50"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell51"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell52"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell53"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell54"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row7"> <td class="td" id="cell55"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell56"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell57"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell58"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell59"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell60"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell61"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell62"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell63"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row8"> <td class="td" id="cell64"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell65"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell66"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell67"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell68"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell69"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell70"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell71"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell72"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row9"> <td class="td" id="cell73"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell74"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell75"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell76"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell77"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell78"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell79"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell80"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell81"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> </table>

To make the empty cells editable, you can mix the contenteditable attribute and input together in the table cells:

if(sudoku[i][j] === null){
  table.rows[i].cells[j].setAttribute("contenteditable", "true");                   
} else {
  table.rows[i].cells[j].textContent = sudoku[i][j];
}

To restrict the input to 1 to 9 and to only one number, you can use some event listeners:

table.addEventListener("keypress", function(e){
   if (e.which < 49 || e.which > 57) e.preventDefault();
});

table.addEventListener("input", function(e){
  e.target.value = e.data;
});

I also added some CSS to make the table print out a bit nicer.

 let sudoku = [ [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null, null], ]; window.onload = function () { generateSudoku(61); fillEmptySudoku(); }; function generateSudoku(displayedNumbers) { let numAdded = 0; while (numAdded < displayedNumbers) { let row = Math.floor(Math.random() * 9); let col = Math.floor(Math.random() * 9); let number = Math.floor(Math.random() * 9) + 1; if (sudoku[row][col] === null) { sudoku[row][col] = number; } else { numAdded++; } } return sudoku; } let table = document.getElementById("table"); //enter the matrix value into the html table function fillEmptySudoku() { for (let i = 0; i < table.rows.length; i++) { for (let j = 0; j < table.rows[i].cells.length; j++) { if(sudoku[i][j] === null){ table.rows[i].cells[j].setAttribute("contenteditable", "true"); } else { table.rows[i].cells[j].textContent = sudoku[i][j]; } } } } //only allow 1 to 9 in cells table.addEventListener("keypress", function(e){ if (e.which < 49 || e.which > 57) e.preventDefault(); }); //restrict inputs to one number only table.addEventListener("input", function(e){ e.target.value = e.data; });
 table { border-collapse: collapse; width: 180px; text-align: center; } td { border: 1px solid black; min-width: 25px; } td:nth-of-type(3) { border-right: 3px solid black; } td:nth-of-type(6) { border-right: 3px solid black; } tr:nth-of-type(3) { border-bottom: 3px solid black; } tr:nth-of-type(6) { border-bottom: 3px solid black; } input { width: 20px; text-align: center; } /* Chrome, Safari, Edge, Opera */ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } /* Firefox */ input[type=number] { -moz-appearance: textfield; }
 <table id="table"> <tr class="tr" id="row1"> <td class="td" id="cell1"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell2"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell3"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell4"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell5"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell6"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell7"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell8"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell9"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row2"> <td class="td" id="cell10"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell11"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell12"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell13"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell14"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell15"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell16"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell17"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell18"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row3"> <td class="td" id="cell19"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell20"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell21"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell22"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell23"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell24"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell25"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell26"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell27"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row4"> <td class="td" id="cell28"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell29"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell30"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell31"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell32"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell33"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell34"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell35"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell36"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row5"> <td class="td" id="cell37"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell38"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell39"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell40"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell41"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell42"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell43"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell44"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell45"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row6"> <td class="td" id="cell46"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell47"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell48"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell49"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell50"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell51"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell52"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell53"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell54"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row7"> <td class="td" id="cell55"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell56"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell57"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell58"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell59"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell60"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell61"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell62"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell63"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row8"> <td class="td" id="cell64"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell65"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell66"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell67"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell68"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell69"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell70"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell71"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell72"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> <tr class="tr" id="row9"> <td class="td" id="cell73"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell74"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell75"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell76"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell77"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell78"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell79"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell80"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> <td class="td" id="cell81"> <input type="number" min="1" max="9" step="1" class="inp" /> </td> </tr> </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM