1

I'm trying to place random object in a dynamic grid using only javascript. I'm stuck on how to place random objects/images in the grid. Something like minesweeper but looking for simple example to start with.

This is the link of the post I was following Creating a dynamic grid of divs with Javascript

Code below:

<html><head> 
<script language="javascript"> 
function genDivs(v){ 
  var e = document.body; // whatever you want to append the rows to: 
  for(var i = 0; i < v; i++){ 
    var row = document.createElement("div"); 
    row.className = "row"; 
    for(var x = 1; x <= v; x++){ 
        var cell = document.createElement("div"); 
        cell.className = "gridsquare"; 
        cell.innerText = (i * v) + x;
        row.appendChild(cell); 
    } 
    e.appendChild(row); 
  } 
  document.getElementById("code").innerText = e.innerHTML;

 }
 </script> 
 </head> 
<body> 
  <input type="button" onclick="genDivs(6)" value="click me"> 
   <code id="code"></code>
</body> 
</html> 
Community
  • 1
  • 1
icode
  • 637
  • 2
  • 10
  • 22

3 Answers3

0

.innerText is non-standard; use .textContent instead (see https://stackoverflow.com/a/19032002 and https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent for differences).

Consider putting your rows and cells within a div container to avoid polluting the rest of the HTML. Something like this:

<html>
<head>
<!--`language` attribute is deprecated-->
<script type="text/javascript">
function genDivs(v) {
  var e = document.querySelector("#container"); // container div
  for(var i = 0; i < v; i++) { 
    var row = document.createElement("div"); 
    row.className = "row"; 
    for(var x = 1; x <= v; x++) { 
        var cell = document.createElement("div"); 
        cell.className = "gridsquare"; 
        cell.textContent = (i * v) + x; // Use .textContent instead of .innerText
        row.appendChild(cell); 
    } 
    e.appendChild(row); 
  } 
  document.getElementById("code").textContent = e.innerHTML; // Same thing here

 }
 </script> 
 </head>
<body>
  <input type="button" onclick="genDivs(6)" value="Generate some results!"> 
  <div id="container"></div>
  <code id="code"></code>
</body> 
</html>
Community
  • 1
  • 1
Kyle Feng
  • 1
  • 2
0

Maybe this example will help you further:

I've added a function 'generateRandomNumbers' that will return an array with random numbers. So generateRandomNumbers(6) will give you an array with the numbers 1-36 in a random order.

Then when creating a cell, I take an element from that array with random numbers and add that to the "innerHTML" of the cell.

function genDivs(v) {
        document.getElementById("code").innerHTML = "";
        var randomNumbers = generateRandomNumbers(v);

        for (var i = 0; i < v; i++) {
            var row = document.createElement("div");
            row.className = "row";
            for (var x = 1; x <= v; x++) {
                var cell = document.createElement("div");
                cell.className = "gridsquare";
                cell.innerHTML = randomNumbers.pop();
                row.appendChild(cell);
            }
            document.getElementById("code").appendChild(row);
        }
    }
    // Code for this random function found on: http://stackoverflow.com/questions/2380019/generate-unique-random-numbers-between-1-and-100
    function generateRandomNumbers(number) {
        var randomNumbers = number * number;
        var arr = [];
        while(arr.length < randomNumbers){
            var randomnumber=Math.ceil(Math.random()*randomNumbers);
            var found=false;
            for(var i=0;i<arr.length;i++){
                if(arr[i]==randomnumber){found=true;break}
            }
            if(!found)arr[arr.length]=randomnumber;
        }
        return arr;
    }
.gridsquare {
  display: inline-block;
  border: 1px solid #000;
  width: 20px;
  height: 20px;
  padding: 3px;
  margin: 2px;
}
<input type="button" onclick="genDivs(6)" value="click me">
<code id="code"></code>
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • I like how this is structure little more code than William example but I see what's going on. It's similar to the one I just figured out but I'm only returning 1 or 0. If 1 append box if 0 append blank box div's. – icode Nov 07 '15 at 18:51
0

Here is a working version:

<style>
    .row { width: 100%; clear: both; text-align: center; }
    .col { display: inline-block; min-height: 20px; min-width: 20px; padding: 8px 10px; background-color: #ededed; margin: 1px; }
    .col:hover { background-color: #333333; color: #ffffff; }
</style>

<input type="button" onClick="genDivs(6);" value="click me" /> 
<div id="target"></div>

<script language="javascript"> 
function genDivs(rows,cols){ 
  var e = document.getElementById("target");
  cols = cols || rows;
  for(var r = 0; r < rows; r++) {
    var row = document.createElement("div");
    row.className = "row";
    for(var c = 0; c < cols; c++) {
       var col = document.createElement("div");
       col.className = "col";
       col.innerHTML = (r * rows) + c;
       col.innerHTML = getElement();
       row.appendChild(col);
    } 
    e.appendChild(row);
  } 
 }
 function getElement(){
    var elements = [ 
        "A",
        "B",
        "C"
    ]
    return elements[Math.floor(Math.random() * (elements.length))];
 }
</script>    

This is easier with jQuery. I used vanilla Javacript. I'd usually put the onclick in the javascript, but I left it as is for you.

Here's a jsfiddle: https://jsfiddle.net/mckinleymedia/chLLg4rr/

Hope this helps.


Per request, I've made a jQuery version. I also used lodash to make this more efficient(lodash comes in really handy). And I've more properly separated the script, the html and the styles - these should each go in a different file. Here's a jsfiddle: https://jsfiddle.net/mckinleymedia/btb9vp26/

script:

function grid(rows,cols,target){ 
  cols = cols || rows;
  target = target || "grid";
  var gridDiv = $("." + target);
  gridDiv.html(''); // clear grid to reload
  _.times(rows, function() {
    gridDiv
        .each(function(){ // allows multiple grids
            $(this).append(addRows(rows,cols));
        });
 });
};
function addRows(rows,cols){
    return $("<div />")
                .addClass("row")
                .html(
                    addCols(cols)
                );
};
function addCols(cols){
    return _.times(cols, function() {
        return $("<div />")
            .addClass("col")
            .html( getElement() );
     });
};
function getElement(){
    var elements = [ 
        "A",
        "B",
        "C"
    ];
    return _.sample(elements);
};
$(".js-grid").click( function(){ grid(6,10) } );
$(".js-grid2").click( function(){ grid(3,5,'grid2') } );

html:

<button type="btn btn-info" class="js-grid">Click me</button> 
<button type="btn btn-info" class="js-grid">Or me</button> 
<button type="btn btn-info" class="js-grid2">Grid 2</button> 
<div class="grid"></div><div class="grid2"></div>
<div class="grid"></div>

styles:

.row { width: 100%; clear: both; text-align: center; }
.col { display: inline-block; min-height: 20px; min-width: 20px; padding: 8px 10px; background-color: #ededed; margin: 1px; }
.col:hover { background-color: #333333; color: #ffffff; }
.grid, .grid2 { margin-bottom: 10px; }
  • I like how your code works but have a question on why you used cols = cols || rows; – icode Nov 07 '15 at 18:38
  • I added that to enable passing in rectangles that aren't square. If you just use this: genDivs(6), it'll make a 6x6 square. If you do this: genDivs(6,8), it'll make a 6x8 rectangle. cols = cols || rows; will leave cols, if it has been passed in, but will set it to the same as rows if it has not. Test it by changing the onclick to genDivs(6,8); – William Schroeder McKinley Nov 07 '15 at 18:43
  • Okay, I see what you mean. Good I learned something new. If you have time can you show how to do this in jQuery. Thanks – icode Nov 07 '15 at 18:56
  • Sure. Looks like It's too long for a comment - I'll put it in the answer above.... – William Schroeder McKinley Nov 08 '15 at 05:56