You have 2 very basic problems with your code: 1. Usage of append() The content you append() should be valid html in its own right. For example, your first append does $(this).append('<table>'), when it should really be $(this).append('<table></table>') which would insert a TABLE element as the last child of the element referred to by *this*. Likewise with rows - $(this).append('<tr></tr>') - and cells - $ (this).append('<td></td>') - etc.
2. What you are appending to, ie *this* In each and every case you are appending to $(this), where *this* refers to the #mytable element that was originally clicked upon. For the first append, the TABLE, this would be fine; however, when you append a row (TR), for example, you actually want to append it to the TABLE just added, not to *this*! Similarly for cells, you should be appending the TDs to the rows (the TRs), not to *this*. As an (extremely simple) example, appending a single row, single celled table might look like... $(this).append('<table></table>'); $('table', this).append('<tr></tr>'); $('tr', this).append('<td>Cell content</td>'); As you can probably tell, this is not going to be a particularly useful procedure to follow for very long if I wanted to add more rows and cells, because either, the selector is going to get progressively more complex trying to keep up with which element I am appending to, or, I'm going to have to start storing stuff in variables. Either way, it's a waste of effort having to keep going back to the DOM to find the elements I've just added so that I can then append to them. As Jason has already pointed out, you would be better off constructing your table's html and then doing a single append to the #mytable element. An alternative to using string concatenation is use an array. For example, using "var a=..." from your code above, your click function might resemble... $('#mytable').click(function(){ var table = [] , numRows = a.length , numCells = a.length ? a[0].length : 0 , r, c; if(numCells){ table.push('<table><thead>'); // ... header row if needed? table.push('</thead><tbody>'); for(r=0; r<numRows; r++){ table.push('<tr>'); for(c=0; c<numCells; c++){ table.push('<td>' + a[r][c] + '</td>'); } table.push('</tr>'); } table.push('</tbody></table>'); $(this).append(table.join('')); } }); On Jan 19, 6:59 am, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote: > My use case is pretty common and surely it is in some tutorial but I > cannot find the right place > where to look, so let me post here. I would like to generate an HTML > table from JSON data > coming from a server. > I am a very green when it comes to Javascript, so naively I wrote the > following > code: > > var a = [["a","b","c"],[1,2,3],[4,5,6]]; // the array will be read > from the server in the real app > > $("#mytable").click(function() > { > $ > (this).append("<table>"); > $ > (this).append("<thead>"); > $ > (this).append("<tr>"); > for(j=0; j<3; j++) > { > $(this).append("<th>" + a[0][j] + "</ > th>");}; > $(this).append("</ > tr>"); > $(this).append("</ > thead>"); > $ > (this).append("<tbody>"); > for(i=1; i<3; i++) > { > $ > (this).append("<tr>"); > for(j=0; j<3; j++) > { > $(this).append("<td>" + a[i][j] + "</ > td>"); }; > $(this).append("</ > tr>"); }; > $(this).append("</ > tbody>"); > $(this).append("</ > table>"); > }); > > When I click on #mytable and I look at the generated HTML with Firebug > I get > > <table/> > <thead/> > <tr/> > <th>a</th> > <th>b</th> > <th>c</th> > <tbody/> > <tr/> > <td>1</td> > <td>2</td> > <td>3</td> > <tr/> > <td>4</td> > <td>5</td> > <td>6</td> > > What's happening here? It seems .append is inserting closed tags > instead of what I told > it to append. I am pretty convinced that I should have generated the > tags with > document.createElement instead, but I did expect .append to work for > a quick and > dirty experiment. Anybody here can shed some light? > TIA, > > Michele Simionato