0

I have a code to populate a table using Javascript as:

var myResponse = document.getElementById("jsonPlaceHolder");
myResponse.innerHTML += "<table border=1> <tr> <td> User Id </td> <td> Question </td> <td> Link Question </td>  </tr>";
for (var i = 0; i < 25; i++) {
    myResponse.innerHTML += "<tr>"
    myResponse.innerHTML += "<td>" + jsonObj[i]["user_id"] + "</td>";
    myResponse.innerHTML += "<td>" + jsonObj[i]["text"] + "</td>";
    myResponse.innerHTML += "</tr>"
}
myResponse.innerHTML += "</table>";

Problem with this code is when I run this table is not continued inside for loop. If I add

        myResponse.innerHTML += "<table><tr>"

inside my for loop, table is created. Isn't this bit odd?,

since i am using += to add to current innerHTML of the DOM element.

2 Answers 2

4

One of the most misunderstood thing about innerHTML stems from the way the API is designed. It overloads the + and = operators to perform DOM insertion. This tricks programmers into thinking that it is merely doing string operations when in fact innerHTML behaves more like a function rather than a variable. It would be less confusing to people if innerHTML was designed like this:

element.innerHTML('some html here'); unfortunately it's too late to change the API so we must instead understand that it is really an API instead of merely an attribute/variable.

When you modify innerHTML it triggers a call to the browser's HTML compiler. It's the same compiler that compiles your html file/document. There's nothing special about the HTML compiler that innerHTML calls. Therefore, whatever you can do to a html file you can pass to innerHTML (the one exception being that embedded javascript don't get executed - probably for security reasons).

This makes sense from the point of view of a browser developer. Why include two separate HTML compilers in the browser? Especially considering the fact that HTML compilers are huge, complex beasts.

The down side to this is that incomplete HTML will be handled the same way it is handled for html documents. In the case of elements not inside a table most browsers will simply strip it away (as you've observed for yourself). That is essentially what you're trying to do - create invalid/incomplete HTML.

The solution is to provide innerHTML with complete HTML:

    var htmlString = "<table border=1> <tr> <td> User Id </td> <td> Question </td> <td> Link Question </td>  </tr>";
    for (var i = 0; i < 25; i++) {
        htmlString  += "<tr>"
        htmlString  += "<td>" + jsonObj[i]["user_id"] + "</td>";
        htmlString  += "<td>" + jsonObj[i]["text"] + "</td>";
        htmlString  += "</tr>"
    }
    htmlString += "</table>"
    myResponse.innerHTML += htmlString;
Sign up to request clarification or add additional context in comments.

Comments

1

Use the DOM API to manipulate the DOM:

var myResponse = document.getElementById("jsonPlaceHolder");
var table = document.createElement('table'),
    headings = ["User ID", "Question", "Link Question"];
table.style.border = "1";

var r = table.insertRow(-1);

for (var i = 0; i < 3; i++) {
    (function(){
        return r.insertCell(-1);
    })().innerHTML = heading[i];
}

for (var i = 0; i < 25; i++) {
    r = table.insertRow(-1);

    var userid = r.insertCell(-1),
        text = r.insertCell(-1);

    userid.innerHTML = jsonObj[i]["user_id"];
    text.innerHTML = jsonObj[i]["text"];
}

myResponse.appendChild(table);

5 Comments

yes i can certainly do that.. this may work.. but why is this thing not working ? You have any clue ?
@CodeMonkey slebetman explains why your original code does not work in his answer. A browser's HTML parser is designed to be fault tolerant, so it tries to correct the incomplete HTML you add insert into the DOM at each stage by stripping it or trying to complete it.
You forgot the part where it's added to the DOM. I think you need myResponse.appendChild(table); at the end.
@CodeMonkey I would definitely use this method in favor of innerHTML. It has a structure, should be less error-prone, and is more concise/logical...instead of just setting an element's contents with a new string of HTML.
@Asad Also, your insertRow and insertCell calls require an index parameter be passed to them. It probably makes sense to always pass -1 so that the row/cell is appended to the end.

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.