0

I have an assignment to write JavaScript which will create a table(x columns, y rows...) and I managed to do that. I have a problem with writing to the html page.

My code:

document.write('<table border = \"3\">');
      while(i <= y) 
      {
        document.write('<tr>');
        j = 0;
        while(j <= x) 
          {
            if (i == 0) 
          {
              if (j == 0)
              {
                document.write(' <th></th> ');
              }
              else               
              {
                document.write('<th>');
                document.write("x = " + j);
                document.write('</th>');
              }             
          }
          else 
          {
            if (j == 0) 
              {
                document.write('<th>');
                document.write("y = " + i);
                document.write('</th>');
              }
            else
              {
                document.write('<td>');
                document.write(operation(i,j));
                document.write('</td>');
              }
          }
          j++;
        }
      document.write('</tr>');
      i++;
    } 
  document.write('</table>');  
  }

I guess it is overwriting the page because of document.write? How can I change this?

Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
ivanz
  • 712
  • 2
  • 11
  • 30

2 Answers2

3

Please don't use document.write. See Why is document.write discouraged.

I think your use of document.write means it overwrite's the entire page. This is working as intended if you call the function after the page has loaded. All calls to document.write after the document is loaded creates a new document. We prefer DOM manipulation since it a safe way to directly edit the DOM that doesn't involve string manipulation.

Writing HTML as text should be left to the browser which parses a HTML file and loads it.

// feature detection for cross browser compliance.
var txt = function(node, text) {
    if (node.innerText !== undefined) {
        node.innerText = text; 
    } else if (node.textContent !== undefined) {
        node.textContent = text;    
    }
}

function createTable(rows, columns) {
    var table = document.createElement("table");
    table.border = '3';
    var tbody = document.createElement("tbody");
    var thead = document.createElement("thead");
    for (var i = 0; i < rows; i++) {
        var tr = document.createElement("tr");
        for (var j = 0; j < columns; j++) {
            var cell;
            if (i === 0) {
                cell = document.createElement("th");
                if (j !== 0) {
                    txt(cell, "x = " + j);
                }
            }
            else {
                if (j == 0) {
                    cell = document.createElement("th");
                    txt(cell, "y = " + i);
                }
                else {
                    cell = document.createElement("td");
                    txt(cell, operation(i, j));
                }
            }
            tr.appendChild(cell);
        }
        if (i === 0) {
            thead.appendChild(tr);    
        } else {
            tbody.appendChild(tr);    
        }
    }
    table.appendChild(thead);
    table.appendChild(tbody);

    return table;
}

Using DOM manipulation you could do it like above. There may be a few optimisations I missed. Live example (only tested chrome 10)

At least it works as intended.

Let me know if you want to see an implementation in say jQuery or some other DOM manipulation library. The code will be a lot nicer and more robust in terms of cross browser compliance.

Community
  • 1
  • 1
Raynos
  • 156,883
  • 55
  • 337
  • 385
  • i didn't saw this answer. I have implemented somethig like this. instead of document.write i have stored all tags in one variable and at the end, just used document.getElementById("divid").innerHTML=s;. thank you – ivanz Mar 21 '11 at 09:08
  • @sevdah using `.innerHTML` is still manipulation HTML as a string. Like I mentioned this should be left to the browser. I recommend you use DOM manipulation directly and also recommend you use a DOM manipulation library like mootools or jQuery if your doing a significant amount of this throughout your website. – Raynos Mar 21 '11 at 09:44
  • i appreciate your suggestions, and i will have that on my mind in future, but this was homework and one of the mandatory requests was not to use libraries. – ivanz Mar 21 '11 at 19:00
0

I see a number of problems here. First and foremost, I don't believe your code is properly balanced. I believe as a first step it should look more like:

<script language="javascript">
    document.write('<table border = \"3\">');
    while(i <= y) {
        document.write('<tr>');
        j = 0;
        while(j <= x) {
            if (i == 0) {
                if (j == 0) {
                    document.write(' <th></th> ');
                } else {
                    document.write('<th>');
                    document.write("x = " + j);
                    document.write('</th>');
                }             
            } else {
                if (j == 0) {
                    document.write('<th>');
                    document.write("y = " + i);
                    document.write('</th>');
                } else {
                    document.write('<td>');
                    document.write(operation(i,j));
                    document.write('</td>');
                }
            }
            j++;
        }
        document.write('</tr>');
        i++;
    } 
    document.write('</table>');  
    </script>

Secondarily it looks to me like you're never really ever instantiating i, and while you do it with j, you're not doing it early enough.

At the line while(i <= y) the interpreter is basically seeing:

while (undefined <= undefined) {

At some level, I'm honestly not sure that document.writes is really the best solution for you, I would probably recommend using document.createElement instead, but that's perhaps more of a personal preference.

Attempting to step a level further out yet sticking with your methodology, I might look toward something like:

function generateTable (width, height) {
    document.write("<table border=\"3\">");
    var i = 1;
    while (i <= height) {
        document.write("<tr>");
        var j = 1;
        while (j <= width) {
            if (i == 0) {
                // header row
                document.write("<th>"+ j +" x "+ i +"</th>");
            } else {
                document.write("<td>"+ j +" x "+ i +"</td>");
            }
            j++;
        }
        document.write("</tr>");
        i++;
    }
    document.write("</table>");
}

generateTable(5, 10);
whoughton
  • 1,365
  • 11
  • 20
  • thank you for your reply.. so, this should solve my problem with overwriting ? This is not the full code, just the part with writing to the doc :) – ivanz Mar 20 '11 at 19:45
  • I'm honestly not sure what overwriting issue you were seeing, given the limited context, but it seems to write out reasonably well in my limited testing. – whoughton Mar 20 '11 at 20:10
  • everything from my layout disappear, only the created table is there – ivanz Mar 20 '11 at 20:21
  • @sevdah any call to document.write after the document is loaded creates a new document. I.e. it empties your current one. – Raynos Mar 21 '11 at 09:45