Search code examples
javascriptformsfor-loopdynamic-tables

Trying to create a dynamic table with vanilla Javascript, code not working


What I'm trying to build:

I'm trying to build a Pixel Art Maker, which is essentially an empty grid of user-determined size, and the colour of each box in the grid changes when you click on it.

Problem:

I managed to figure out the colour change, but can't get the table to appear at all.

I've already looked at creating-a-dynamic-table-based-on-a-user-input which appears to be the closest thing I could find to what I'm attempting to achieve. There's a similar logic to the tables, but I'm too inexperienced to understand the differences between that code and mine.

Codepen:

Codepen link

And here is my code snippet:

const canvas = document.querySelector('#pixelCanvas')

const tbody = document.createElement('tbody');

canvas.addEventListener('click', function(e) {
  e.target.style.background = 'black';
});

canvas.addEventListener('dblclick', function(e) {
  e.target.style.backgroundColor = 'white';
});

// Store the value of columns
const column = document.getElementById('column').value;

// Store the value of rows
const row = document.getElementById('row').value;

// Access forms
const submitForm = document.querySelector('#submitForm');

submitForm.addEventListener('submit', function(e) {
  e.preventDefault(); // Prevents the submit button from refreshing the page by default
  debugger;
  for (r = 0; r < row; r++) {
    const tr = document.createElement('tr');
    tbody.appendChild(tr);
    for (c = 0; c < column; c++) {
      const td = document.createElement('td');
      tr.appendChild(td);
    }
    canvas.appendChild(tbody);
  }



});
<h1>Pixel Art Maker</h1>

<fieldset>
  <legend>Grid Size</legend>

  <form id='submitForm'>

    <label for="height">Columns:</label>
    <input type="number" id="column" placeholder="Key in an integer" step="1" />

    <label for="width">Rows:</label>
    <input type="number" id="row" placeholder="Min: 1, max: 100" min="1" max="100" />

    <div>
      <input type="submit" id="submit" value="Submit" />
    </div>
  </form>
</fieldset>

<br>

<div>
  <table id="pixelCanvas">
    <!--  Dynamic pixel canvas  -->
  </table>
</div>


Solution

  • This is because you have called the no of rows and columns at starting so its NULL at initial, get no of rows and column after click submit.
    Checkout this fiddle: https://jsfiddle.net/hdsbvtLw/2/

    const canvas = document.querySelector('#pixelCanvas')
    
    const tbody = document.createElement('tbody');
    
    canvas.addEventListener('click', function(e){
      e.target.style.background = 'black';
    });
    
    canvas.addEventListener('dblclick', function(e){
      e.target.style.backgroundColor = 'white';
    });
    
    // Store the value of columns
    
    
    // Access forms
    const submitForm = document.querySelector('#submitForm');
    
    submitForm.addEventListener('submit', function(e){
      e.preventDefault();  // Prevents the submit button from refreshing the page by default
      tbody.innerHTML='';
      const column = document.getElementById('column').value;
    
    // Store the value of rows
    const row = document.getElementById('row').value;
      console.log(row);
      for (r = 0; r < row; r++) {
        const tr = document.createElement('tr');
        tbody.appendChild(tr);
        for (c = 0; c < column; c++) {
          const td = document.createElement('td');
          tr.appendChild(td);
        } 
        canvas.appendChild(tbody);  
      }
      
      
      
    });
    /**
     * index.scss
     * - Add any styles you want here!
     */
    body {
      background: #f5f5f5;
    }
    
    table, thead, tbody, tfoot, tr, td {
      border-collapse: collapse;
      border: 3px solid black;
    }
    
    td {
      width: 30px;
    }
    
    tr {
      height: 30px;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
      
      <!--  Meta  -->
      <meta charset="UTF-8" />
      <title>Pixel Art</title>
      
      <!--  Styles  -->
      <link rel="stylesheet" href="styles/index.processed.css">
    </head>
    <body>
      
      <h1>Pixel Art Maker</h1>
      
      <fieldset>
        <legend>Grid Size</legend>
        
        <form id = 'submitForm'>
        
        <label for="height">Columns:</label>
        <input type="number" id="column" 
               placeholder="Key in an integer" step="1" />
    
        <label for="width">Rows:</label>
        <input type="number" id="row"
               placeholder="Min: 1, max: 100"
               min="1" max="100" />
          
            <div>
                <input type="submit" id="submit" value="Submit" />
          </div>
        </form>
      </fieldset>
      
      <br>
      
      <div>
        <table id="pixelCanvas">
          <!--  Dynamic pixel canvas  -->
        </table>
      </div>
      
      <!-- Scripts -->
      <script src="scripts/index.js"></script>
    </body>
    </html>