90

Possible duplicate Nested elements

I'm getting from server-side ajax response (Json) and I'm trying to dynamically create table rows and append them to an existing table with id=records_table.

I tried to implement the solution in possible duplicate but it failed.

My response looks like that:

    '[{
      "rank":"9",
      "content":"Alon",
      "UID":"5"
     },
     {
       "rank":"6",
       "content":"Tala",
       "UID":"6"
    }]'

the require result is something like that:

<tr>
   <td>9</td>
   <td>Alon</td>
   <td>5</td>  
</tr>
<tr>
   <td>6</td>
   <td>Tala</td>
   <td>5</td>  
</tr>

I want to do something without parsing the Json so I tried to do the following, which of course was a disaster:

    function responseHandler(response)
    {

        $(function() {
            $.each(response, function(i, item) {
                $('<tr>').html(
                    $('td').text(item.rank),
                    $('td').text(item.content),
                    $('td').text(item.UID)
                ).appendTo('#records_table');

            });
        });


    }

From my solution I get only one row with the number 6 in all cells. What am I doing wrong?

user5305519
  • 3,008
  • 4
  • 26
  • 44
Canttouchit
  • 3,149
  • 6
  • 38
  • 51

12 Answers12

155

Use .append instead of .html

var response = "[{
      "rank":"9",
      "content":"Alon",
      "UID":"5"
     },
     {
       "rank":"6",
       "content":"Tala",
       "UID":"6"
    }]";

// convert string to JSON
response = $.parseJSON(response);

$(function() {
    $.each(response, function(i, item) {
        var $tr = $('<tr>').append(
            $('<td>').text(item.rank),
            $('<td>').text(item.content),
            $('<td>').text(item.UID)
        ); //.appendTo('#records_table');
        console.log($tr.wrap('<p>').html());
    });
});
drizzie
  • 3,351
  • 2
  • 27
  • 32
  • This is not working I think because my response response is as string "[{ "rank":"9", "content":"Alon", "UID":"5" }, { "rank":"6", "content":"Tala", "UID":"6" }]" – Canttouchit Jul 18 '13 at 13:16
  • 1
    this [works](http://jsfiddle.net/rrzZU/) and enables to manage `td` elements clean – Saic Siquot Jul 18 '13 at 13:25
  • 3
    I updated the solution. You need to convert your string to JSON using jQuery's $.parseJSON function. http://jsfiddle.net/abduncan/rrzZU/1/ – drizzie Jul 18 '13 at 13:35
  • 3
    appending data using jQuery is not a good idea for large data. You will end up browser render issue. Instead we can use join() to generate truncated string to show – shivg Jun 01 '16 at 08:51
  • 1
    Hi, but how is this response connected to adding this information to the html #recordsTable? – GoldenEagle Jul 22 '16 at 19:32
  • 2
    If you look at the 4th line from the bottom containing the comment `//.appendTo('#records_table');`, it shows how you would append the records to the DOM. It is commented out in this answer and instead the result is written to the console for testing purposes. – drizzie Jul 22 '16 at 20:34
  • Can rows be clickable ? @drizzie – alper Oct 26 '18 at 11:30
  • 1
    append will attach the records but will not clear the existing records when the event is fired multiple times. Better option would be to clear records initially and the call append. – Kurkula Mar 06 '19 at 22:00
  • Suppose if i have any update button i need to write that button inside td element then does it works. I have aproblem in creating a button inside td element. OnClick event is not working inside td . – Ravi Nov 11 '19 at 07:43
44

Try this (DEMO link updated):

success: function (response) {
        var trHTML = '';
        $.each(response, function (i, item) {
            trHTML += '<tr><td>' + item.rank + '</td><td>' + item.content + '</td><td>' + item.UID + '</td></tr>';
        });
        $('#records_table').append(trHTML);
    }

Fiddle DEMO WITH AJAX

Nono
  • 6,986
  • 4
  • 39
  • 39
11

Here is a complete answer from hmkcode.com

If we have such JSON data

// JSON Data
var articles = [
    { 
        "title":"Title 1",
        "url":"URL 1",
        "categories":["jQuery"],
        "tags":["jquery","json","$.each"]
    },
    {
        "title":"Title 2",
        "url":"URL 2",
        "categories":["Java"],
        "tags":["java","json","jquery"]
    }
];

And we want to view in this Table structure

<table id="added-articles" class="table">
            <tr>
                <th>Title</th>
                <th>Categories</th>
                <th>Tags</th>
            </tr>
        </table>

The following JS code will fill create a row for each JSON element

// 1. remove all existing rows
$("tr:has(td)").remove();

// 2. get each article
$.each(articles, function (index, article) {

    // 2.2 Create table column for categories
    var td_categories = $("<td/>");

    // 2.3 get each category of this article
    $.each(article.categories, function (i, category) {
        var span = $("<span/>");
        span.text(category);
        td_categories.append(span);
    });

    // 2.4 Create table column for tags
   var td_tags = $("<td/>");

    // 2.5 get each tag of this article    
    $.each(article.tags, function (i, tag) {
        var span = $("<span/>");
        span.text(tag);
        td_tags.append(span);
    });

    // 2.6 Create a new row and append 3 columns (title+url, categories, tags)
    $("#added-articles").append($('<tr/>')
            .append($('<td/>').html("<a href='"+article.url+"'>"+article.title+"</a>"))
            .append(td_categories)
            .append(td_tags)
    ); 
});  
hmkcode
  • 111
  • 2
9

Try it like this:

$.each(response, function(i, item) {
    $('<tr>').html("<td>" + response[i].rank + "</td><td>" + response[i].content + "</td><td>" + response[i].UID + "</td>").appendTo('#records_table');
});

Demo: http://jsfiddle.net/R5bQG/

tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • Can it be improved? I want to have a control on the on the cells as well, for example if I want to set an attribute inside td. – Canttouchit Jul 18 '13 at 13:04
  • Sure, you can do this many ways, you can build each TD, then append, or you can set the attribute directly in the tag above. What attribute are you looking to add, ill provide an example. – tymeJV Jul 18 '13 at 13:08
  • This is not working I think because my response response is as string `"[{ "rank":"9", "content":"Alon", "UID":"5" }, { "rank":"6", "content":"Tala", "UID":"6" }]"` – Canttouchit Jul 18 '13 at 13:14
6
$.ajax({
  type: 'GET',
  url: urlString ,
  dataType: 'json',
  success: function (response) {
    var trHTML = '';
    for(var f=0;f<response.length;f++) {
      trHTML += '<tr><td><strong>' + response[f]['app_action_name']+'</strong></td><td><span class="label label-success">'+response[f]['action_type'] +'</span></td><td>'+response[f]['points']+'</td></tr>';
     }
    $('#result').html(trHTML); 
    $( ".spin-grid" ).removeClass( "fa-spin" );
  }
});
Arulkumar
  • 12,966
  • 14
  • 47
  • 68
Iftikhar Khan
  • 313
  • 1
  • 5
  • 9
5

Data as JSON:

data = [
       {
       "rank":"9",
       "content":"Alon",
       "UID":"5"
       },
       {
       "rank":"6",
       "content":"Tala",
       "UID":"6"
       }
       ]

You can use jQuery to iterate over JSON and create tables dynamically:

num_rows = data.length;
num_cols = size_of_array(data[0]);

table_id = 'my_table';
table = $("<table id=" + table_id + "></table>");

header = $("<tr class='table_header'></tr>");
$.each(Object.keys(data[0]), function(ind_header, val_header) {
col = $("<td>" + val_header + "</td>");
header.append(col);
})
table.append(header);

$.each(data, function(ind_row, val) {
row = $("<tr></tr>");
$.each(val, function(ind_cell, val_cell) {
col = $("<td>" + val_cell + "</td>");
row.append(col);
})
table.append(row);
})

Here is the size_of_array function:

function size_of_array(obj) {
    size = Object.keys(obj).length;
    return(size)
    };

You can also add styling if needed:

$('.' + content['this_class']).children('canvas').remove();
$('.' + content['this_class']).append(table);
$('#' + table_id).css('width', '100%').css('border', '1px solid black').css('text-align', 'center').css('border-collapse', 'collapse');
$('#' + table_id + ' td').css('border', '1px solid black');

Result:

enter image description here

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Cybernetic
  • 12,628
  • 16
  • 93
  • 132
4

You shouldn't create jquery objects for each cell and row. Try this:

function responseHandler(response)
{
     var c = [];
     $.each(response, function(i, item) {             
         c.push("<tr><td>" + item.rank + "</td>");
         c.push("<td>" + item.content + "</td>");
         c.push("<td>" + item.UID + "</td></tr>");               
     });

     $('#records_table').html(c.join(""));
}
YD1m
  • 5,845
  • 2
  • 19
  • 23
2

This is working sample that I copied from my project.

 function fetchAllReceipts(documentShareId) {

        console.log('http call: ' + uri + "/" + documentShareId)
        $.ajax({
            url: uri + "/" + documentShareId,
            type: "GET",
            contentType: "application/json;",
            cache: false,
            success: function (receipts) {
                //console.log(receipts);

                $(receipts).each(function (index, item) {
                    console.log(item);
                    //console.log(receipts[index]);

                    $('#receipts tbody').append(
                        '<tr><td>' + item.Firstname + ' ' + item.Lastname +
                        '</td><td>' + item.TransactionId +
                        '</td><td>' + item.Amount +
                        '</td><td>' + item.Status + 
                        '</td></tr>'
                    )

                });


            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest);
                console.log(textStatus);
                console.log(errorThrown);

            }

        });
    }
    
    
    // Sample json data coming from server
    
    var data =     [
    0: {Id: "7a4c411e-9a84-45eb-9c1b-2ec502697a4d", DocumentId: "e6eb6f85-3f44-4bba-8cb0-5f2f97da17f6", DocumentShareId: "d99803ce-31d9-48a4-9d70-f99bf927a208", Firstname: "Test1", Lastname: "Test1", }
    1: {Id: "7a4c411e-9a84-45eb-9c1b-2ec502697a4d", DocumentId: "e6eb6f85-3f44-4bba-8cb0-5f2f97da17f6", DocumentShareId: "d99803ce-31d9-48a4-9d70-f99bf927a208", Firstname: "Test 2", Lastname: "Test2", }
];
  <button type="button" class="btn btn-primary" onclick='fetchAllReceipts("@share.Id")'>
                                        RECEIPTS
                                    </button>
 
 <div id="receipts" style="display:contents">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Transaction</th>
                            <th>Amount</th>
                            <th>Status</th>
                        </tr>
                    </thead>
                    <tbody>

                    </tbody>
                </table>
         </div>
         
 
    
    
    
Malhaar Punjabi
  • 735
  • 7
  • 9
  • i use your only append block, i'm displaying data in bootstrap modal, the problem is it is appending every time and also the previous data. – Ali Raza Aug 01 '19 at 18:39
1

I have created this JQuery function

/**
 * Draw a table from json array
 * @param {array} json_data_array Data array as JSON multi dimension array
 * @param {array} head_array Table Headings as an array (Array items must me correspond to JSON array)
 * @param {array} item_array JSON array's sub element list as an array
 * @param {string} destinaion_element '#id' or '.class': html output will be rendered to this element
 * @returns {string} HTML output will be rendered to 'destinaion_element'
 */

function draw_a_table_from_json(json_data_array, head_array, item_array, destinaion_element) {
    var table = '<table>';
    //TH Loop
    table += '<tr>';
    $.each(head_array, function (head_array_key, head_array_value) {
        table += '<th>' + head_array_value + '</th>';
    });
    table += '</tr>';
    //TR loop
    $.each(json_data_array, function (key, value) {

        table += '<tr>';
        //TD loop
        $.each(item_array, function (item_key, item_value) {
            table += '<td>' + value[item_value] + '</td>';
        });
        table += '</tr>';
    });
    table += '</table>';

    $(destinaion_element).append(table);
}
;
M_R_K
  • 5,929
  • 1
  • 39
  • 40
1

You could do it something like this:

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


    <script>
    $(function(){

    $.ajax({
    url: '<Insert your REST API which you want GET/POST/PUT/DELETE>',
    data: '<any parameters you want to send as the Request body or query string>',
    dataType: json,
    async: true,
    method: "GET"
    success: function(data){

    //If the REST API returned a successful response it'll be stored in data, 
    //just parse that field using jQuery and you're all set

    var tblSomething = '<thead> <tr> <td> Heading Col 1 </td> <td> Heading Col 2 </td> <td> Col 3 </td> </tr> </thead> <tbody>';

    $.each(data, function(idx, obj){

    //Outer .each loop is for traversing the JSON rows
    tblSomething += '<tr>';

    //Inner .each loop is for traversing JSON columns
    $.each(obj, function(key, value){
    tblSomething += '<td>' + value + '</td>';
    });
    tblSomething += '</tr>';
    });

    tblSomething += '</tbody>';

    $('#tblSomething').html(tblSomething);
    },
    error: function(jqXHR, textStatus, errorThrown){
    alert('Hey, something went wrong because: ' + errorThrown);
    }
    });


    });
    </script>


    <table id = "tblSomething" class = "table table-hover"></table>
Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53
0

jQuery.html takes string or callback as input, not sure how your example is working... Try something like $('<tr>').append($('<td>' + item.rank + '</td>').append ... And you have some definite problems with tags fromation. It should be $('<tr/>') and $('<td/>')

Eduard Dyckman
  • 135
  • 1
  • 8
0

I do following to get JSON response from Ajax and parse without using parseJson:

$.ajax({
  dataType: 'json', <----
  type: 'GET',
  url: 'get/allworldbankaccounts.json',
  data: $("body form:first").serialize(),

If you are using dataType as Text then you need $.parseJSON(response)

Harpreet
  • 186
  • 1
  • 1
  • 10