0

I decided to see if I can create an online Sudoku game using HTML, JavaScript, CSS and PHP. So far, I've created the grid but I'm stumped as to why when I try to use an alert box to show their input, I'm either getting "undefined" (when I use .value), blank (when I use .innerText) or the HTML object (when I use .innerHTML). Either I'm missing my coffee but I cannot figure out why neither seem to be working.

My intention is when the user clicks on "Evaluate!", each of the hidden fields (1 for each row) will be populated in a comma-separated format. PHP will receive the content and can break it apart using explode(",", $row), allowing each to be compared as separate arrays against each other. But that's for later.

To save time when reading my code, the problematic area seems to be within the initGrid() function as that's where I'm creating the attributes. I should note, I've checked the console log and there are no errors. Also, I'm trying to do all of this using only JavaScript, not jQuery.

Here's a JSFiddle, although for some reason, my alert boxes aren't working in it but they are in my browser (Chrome, same browser I'm using for JSFiddle).

Here is the troublesome initGrid() function:

function initGrid() {
        var table = document.getElementById("mainTable").getElementsByTagName("tbody")[0];
        var atts = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
        for (var i = 0; i < atts.length; i++) {
            var newRow = table.insertRow(i);
            for (var j = 0; j < 9; j++) {
                var newCell = newRow.insertCell(j);
                newCell.innerHTML = document.getElementById("defaultButtons").innerHTML;
                newCell.setAttribute("name", atts[i] + j);
                newCell.setAttribute("id", atts[i] + j);
                newCell.setAttribute("value", "");
                newCell.setAttribute("onKeyUp", "appendData(this.id, this)");
            }
        }
    }
Cucko Oooo
  • 91
  • 4
  • 14
  • If it helps, when I run your fiddle, I actually do get errors. `Can't find variable: appendData`. I'm suspicious of `this.id`, it seems like it should be `this.getAttribute('id')` – Jerry Apr 29 '14 at 22:37
  • as a side note -- `setAttribute` is almost always the wrong thing to use. 99% of the time, setting the `property` on the `element is better. – Jeremy J Starcher Apr 30 '14 at 01:04
  • @jerry I'm not sure why, but it seems my Chrome doesn't give me any errors but in JSFiddle, it does, even though it's a straight copy and paste (plus the tidy up feature). In http://jsfiddle.net/zRK3d/15/, when I uncomment the commented lines in my notepad++ and run it in Chrome, it does give the correct ID using this.id. – Cucko Oooo Apr 30 '14 at 02:10
  • @JeremyJStarcher I'm seeing all the headaches that setAttribute appears to give. My only reason for using setAttribute was to dynamically set the IDs and names for each input, although if there's a more reliable way, I'm all for it. – Cucko Oooo Apr 30 '14 at 02:12
  • http://stackoverflow.com/questions/8018814/setting-a-property-via-property-or-setattribute – Jeremy J Starcher Apr 30 '14 at 02:15

2 Answers2

0

It maybe isn't clear from your fiddle - but from clicking the "Evaluate" button populateAllHidden() is never being called. In Chrome there is an error logged in the console:

Uncaught ReferenceError: populateAllHidden is not defined

Instead of using onclick in the button:

<button type="button" onClick="populateAllHidden()">Evaluate!</button>

You can give it an ID, and then register an event listener at the same time you initialize the grid. So change the button to:

<button type="button" id="evaluateButton">Evaluate!</button>

In the onload, add the event listener:

window.onload = function () {
    initGrid();
    document.getElementById("evaluateButton").addEventListener("click", populateAllHidden, false);
};

Give that a go - it worked for me!

edwh
  • 58
  • 1
  • 5
  • I made the changes you suggested, as well as some others as seen in http://jsfiddle.net/zRK3d/15/ . I have no idea why but when I uncomment the lines I commented in my JSFiddle, they do work in my Chrome and give the ID correctly. In JSFiddle, it keeps giving undefined, so I'm getting really confused. – Cucko Oooo Apr 30 '14 at 02:07
  • Hi - sorry you're still having trouble. You're seeing the "undefined" in the alert because in your window.onload you calling testCell(), but the testCell is expecting a parameter you've called "x" which you're not passing - so the undefined is because "x" is undefined. – edwh Apr 30 '14 at 16:26
0

After a nice long nap (had only a few hours of sleep when I tried to create the sudoku puzzle), I re-visited it and realized how much of a mess it was. I've since made much more progress and am working on the PHP aspect of it to generate a puzzle. There's also a simple on-screen verification that tells the user whether their input was valid (i.e. a number) or not. Hopefully it can also help someone else, below is sudokuGrid.php:

I just finished writing the verify function and I still have to sort out a few things with it.

<!DOCTYPE html>
<html>
<head>
    <meta charset = "UTF-8" />
    <title>Online Sudoku</title>
    <script type = "text/javascript">
        function initGrid() {
            var tBody = document.getElementById("mainTable").getElementsByTagName("tbody")[0];
            var rowLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
            for(var i = 0; i < rowLetters.length; i++) {
                var newRow = tBody.insertRow(i);
                var rowLabel = newRow.insertCell(0);
                rowLabel.innerHTML = rowLetters[i];
                rowLabel.style.padding = "0px 4px 0px 4px";
                rowLabel.style.fontWeight = "bold";
                for(var j = 1; j < 10; j++) {
                    var newCell = newRow.insertCell(j);
                    var newName = rowLetters[i] + j;
                    newCell.innerHTML = "<input type = 'text' class = 'sudokuCells' value = '' name = " + newName + " maxLength = '1' onInput = 'verify(this)' id = " + newName + " />";
                }
            }
        }

        function verify(x) {
            var valid = document.getElementById("valid");
            var invalid = document.getElementById("invalid");
            valid.style.visibility = "hidden";
            invalid.style.visibility = "hidden";
            if(!isNaN(parseInt((x.value).slice(0, 1)))) {
                valid.style.visibility = "visible";
                invalid.style.visibility = "hidden";
            } else if(((x.value).slice(0, 1)).trim().length == 0) {
                invalid.style.visibility = "hidden";
                valid.style.visibility = "hidden";
            } else {
                invalid.style.visibility = "visible";
                valid.style.visibility = "hidden";
                alert("Sorry, that was an invalid character");
                x.value = "";
            }

        }

        function populateAllHidden() {
            var rowLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
            for(var i = 0; i < rowLetters.length; i++) {
                var hiddenRow = document.getElementById(rowLetters[i] + "_row");
                for(var j = 1; j < 10; j++) {
                    if(j == 1) {
                        hiddenRow.value = document.getElementById(rowLetters[i] + j).value + ",";
                        continue;
                    } else if(j != 9) {
                        hiddenRow.value += document.getElementById(rowLetters[i] + j).value + ",";
                        continue;
                    } else {
                        hiddenRow.value += document.getElementById(rowLetters[i] + j).value;
                    }
                }
            }
            document.getElementById("mainForm").submit();
        }

        window.onload = function() {
            initGrid();
        }
    </script>
    <style>
        .sudokuCells
        {
            width: 15px;
        }

        #valid
        {
            color: #00FF00;
            visibility: hidden;
        }

        #invalid
        {
            color: #FF0000;
            visibility: hidden;
        }

    </style>
</head> 
<body>
    <div id = "mainTableContainer">
        <table border = "1" cellpadding = "0" cellspacing = "0" id = "mainTable">
            <thead>
                <tr>
                    <th></th>
                    <th>a</th>
                    <th>b</th>
                    <th>c</th>
                    <th>d</th>
                    <th>e</th>
                    <th>f</th>
                    <th>g</th>
                    <th>h</th>
                    <th>i</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>
    <div id = "statusContainer">
        <p><strong><span id = "valid">Valid</span> <span id = "invalid">Invalid</span></strong></p>
    </div>
    <form action = "evaluate.php" method = "post" id = "mainForm" >
        <input type = "hidden" name = "a_row" id = "a_row" value = "" />
        <input type = "hidden" name = "b_row" id = "b_row" value = "" />
        <input type = "hidden" name = "c_row" id = "c_row" value = "" />
        <input type = "hidden" name = "d_row" id = "d_row" value = "" />
        <input type = "hidden" name = "e_row" id = "e_row" value = "" />
        <input type = "hidden" name = "f_row" id = "f_row" value = "" />
        <input type = "hidden" name = "g_row" id = "g_row" value = "" />
        <input type = "hidden" name = "h_row" id = "h_row" value = "" />
        <input type = "hidden" name = "i_row" id = "i_row" value = "" />
    </form>
    <button type = "button" onClick = "populateAllHidden()" >Evaluate!</button>
</body>

Cucko Oooo
  • 91
  • 4
  • 14