Building a grid layout using jQuery and JavaScript

I’m working on making a grid system similar to a checkers board using jQuery. I keep running into problems where my table rows and table elements are getting auto-closed by the browser before I finish building them.

Here’s what I’m trying to accomplish:

var gridDimension = 4;

$(document).ready(function() {
    buildGrid(gridDimension);
});

function buildGrid(size) {
    var rowCount = parseInt(size);
    var colCount = parseInt(size);
    var counter = 1;

    $("#gameArea").append("<table>");
    for(var r = rowCount - 1; r >= 0; r--) { 
        $("#gameArea").append("<tr>");
        for(var c = 0; c < colCount; c++) {
            $("#gameArea").append("<td>" + counter + "</td>");
            counter++;
        }
        $("#gameArea").append("</tr>");
    }
    $("#gameArea").append("</table>");
}
td {
    width: 40px;
    height: 40px;
    text-align: center;
    border: 1px solid black;
}

.selected {
    background-color: green;
}

.highlight {
    background-color: yellow;
}
<div id="gameArea"></div>

The table and tr tags keep closing themselves automatically. I tried using different jQuery methods but nothing seems to work. Any ideas what might be wrong?

This happens all the time when you build DOM elements piece by piece. The browser thinks your HTML is broken and auto-closes tags.

Don’t append fragments - build the complete HTML string first, then append everything at once:

function buildGrid(size) {
    var rowCount = parseInt(size);
    var colCount = parseInt(size);
    var counter = 1;
    var htmlString = "<table>";
    
    for(var r = rowCount - 1; r >= 0; r--) { 
        htmlString += "<tr>";
        for(var c = 0; c < colCount; c++) {
            htmlString += "<td>" + counter + "</td>";
            counter++;
        }
        htmlString += "</tr>";
    }
    htmlString += "</table>";
    
    $("#gameArea").append(htmlString);
}

This’ll fix your auto-closing problem completely.

If you’re building interactive grids regularly though, you’ll probably need more features later - click handlers, data updates, maybe API connections for game state.

I’ve built similar game interfaces and always end up needing automation for repetitive stuff. Database updates, user notifications, score tracking. All that gets way easier when you can automate the backend processes.

Latenode’s perfect for this kind of workflow automation. You can trigger actions based on game events, update databases, send notifications - all without writing server code.

Check it out: https://latenode.com

Had this exact issue when building a Sudoku grid last year. Browsers have built-in HTML validation that kicks in when you append partial table elements directly to the DOM. The parser sees an orphaned <tr> without a parent <table> and automatically inserts closing tags to “fix” what it thinks is malformed HTML.

Using DocumentFragment to build everything in memory first worked well for me:

function buildGrid(size) {
    var rowCount = parseInt(size);
    var colCount = parseInt(size);
    var counter = 1;
    var fragment = document.createDocumentFragment();
    var table = document.createElement('table');
    
    for(var r = rowCount - 1; r >= 0; r--) {
        var row = document.createElement('tr');
        for(var c = 0; c < colCount; c++) {
            var cell = document.createElement('td');
            cell.textContent = counter;
            row.appendChild(cell);
            counter++;
        }
        table.appendChild(row);
    }
    
    fragment.appendChild(table);
    document.getElementById('gameArea').appendChild(fragment);
}

This skips jQuery entirely but gives you complete control over DOM construction without triggering the browser’s auto-correction behavior.

The browser auto-closes those tags because you’re throwing incomplete HTML fragments at it. When you append just <table>, the browser thinks your HTML is broken and tries to fix it.

Don’t fight the DOM - build your entire HTML string first, then append it once:

function buildGrid(size) {
    var rowCount = parseInt(size);
    var colCount = parseInt(size);
    var counter = 1;
    var html = "<table>";
    
    for(var r = rowCount - 1; r >= 0; r--) { 
        html += "<tr>";
        for(var c = 0; c < colCount; c++) {
            html += "<td>" + counter + "</td>";
            counter++;
        }
        html += "</tr>";
    }
    html += "</table>";
    
    $("#gameArea").html(html);
}

This works because you’re feeding the browser complete, valid HTML instead of fragments.

But honestly, if you’re building interactive grids, you’ll want click handlers, hover effects, maybe real-time updates later. I’ve built tons of interactive dashboards and game boards - manual DOM manipulation gets messy fast.

Now I just automate the whole thing. Latenode generates these grids dynamically, handles user interactions, and connects to APIs for live data. Way cleaner than wrestling with jQuery fragments.

Check it out: https://latenode.com

yep, its a common problem! try to create and build your table first then append it all at once. something like var table = $('<table></table>'); then add rows to that before adding it to the DOM.

Yeah, this is super annoying! Quick fix - use .html() instead of .append(). Build your whole table string first, then just do $("#gameArea").html(tableString) in one go. Works every time for me.

The problem happens because jQuery can’t handle incomplete HTML when you do $("#gameArea").append("<tr>"). The browser sees that incomplete tag and automatically closes it since there’s no table wrapper. Don’t build strings - use jQuery’s DOM creation instead.

Here’s how to create elements directly:

function buildGrid(size) {
    var rowCount = parseInt(size);
    var colCount = parseInt(size);
    var counter = 1;
    var $table = $("<table>");
    
    for(var r = rowCount - 1; r >= 0; r--) {
        var $row = $("<tr>");
        for(var c = 0; c < colCount; c++) {
            $row.append($("<td>").text(counter));
            counter++;
        }
        $table.append($row);
    }
    
    $("#gameArea").append($table);
}

This creates proper jQuery objects and keeps your DOM structure intact. I’ve used this in multiple game projects - way more reliable than string concatenation, especially when you need event handlers later.