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

Reply via email to