0

Hello!

Why, as a result of this code, all the cells in the table are aligned in one column and don't form a normal table? Sorry for my bad English, and maybe a stupid question, I started learning JS a few days ago

function start () {
    var size = document.getElementById('test5').value;
    document.getElementById('start').style.display = 'none';
    for (var y = 0; y < size; y++) {
        document.getElementById("cont").innerHTML += ('<tr>');
        for (var x = 0; x < size ; x++) {
            document.getElementById("cont").innerHTML += ('<td>test</td>');
        }
        document.getElementById("cont").innerHTML += ('</tr>');
    }
}
    <div >
        <span id="start"><form action="#">
        <p class="range-field">
            <input  type="range" id="test5" min="3" max="9" value="3"/>
        </p>
        </form><br>
            <button type="button" onclick="start()">start</button></span>
        <table border="1" id="cont"></table>
     </div>

1
  • Building HTML with innerHTML is NOT like building a string. Commented Apr 4, 2018 at 17:21

2 Answers 2

2

The problem is that in your loop you assign an incomplete HTML string to innerHTML. After each assignment, the browser does its best to fix the incomplete HTML.

Consider what happens the first time you do this (for brevity we'll assume document.getElementById("cont") has been assigned to a variable named table):

table.innerHTML += '<tr>';

If you then immediately did console.log(table.innerHTML) what you would see is not <tr>, but <tr></tr>. You left that tag open, so the browser closed it for you.

Then, in your loop, you do this:

table.innerHTML += '<td>test</td>';

Since table.innerHTML is already <tr></tr>, the new value you're trying to set it to is <tr></tr><td>test</td>. That isn't valid HTML—a <td> must have a <tr> parent—so the browser fixes it for you by wrapping it in a <tr>. If you did console.log(table.innerHTML) now, you'd see this:

<tr></tr>
<tr><td>test</td></tr>

...and so on. That's why you get all of your cells in a single column.

The solution is to instead start with a temporary string, and only after you've created a complete HTML string, assign it to innerHTML:

const table = document.getElementById('cont');
const sizeInput = document.getElementById('test5');

function start() {
  const size = sizeInput.value;
  
  // build a string named `rowsHtml`
  let rowsHtml = '';
  for (let y = 0; y < size; y++) {
    rowsHtml += '<tr>';
    for (let x = 0; x < size; x++) {
      rowsHtml += '<td>test</td>';
    }
    rowsHtml += '</tr>';
  }

  // now set innerHTML just once
  cont.innerHTML = rowsHtml;
}
<div id="start">
  <input  type="range" id="test5" min="3" max="9" value="3"/>
  <button type="button" onclick="start()">start</button>
</div>
<table border="1" id="cont"></table>

Sign up to request clarification or add additional context in comments.

Comments

1

You are placing your <td>s inside the element with the id of cont. you need to place them inside the <tr> instead. Here is a working solution:

function start () {
    var size = document.getElementById('test5').value;
    let table = document.getElementById("cont");
    document.getElementById('start').style.display = 'none';
    for (var y = 0; y < size; y++) {
        table.innerHTML += ('<tr></tr>');
        for (var x = 0; x < size ; x++) {
        let tr = document.querySelector("#cont tr:last-child");
            tr.innerHTML += ('<td>test</td>');
        }
        document.getElementById("cont").innerHTML += ('</tr>');
    }
}
<div >
        <span id="start"><form action="#">
        <p class="range-field">
            <input  type="range" id="test5" min="3" max="9" value="3"/>
        </p>
        </form><br>
            <button type="button" onclick="start()">start</button></span>
        <table border="1"><tbody id="cont"></tbody></table>
     </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.