Search code examples
jqueryhtmljquery-uilinq.js

generate html table dynamically from json data


I need to generate html table dynamically and list driver_id underneath. It is something similar to pivot but the problem is zone_name can change every day. I'm using jquery and linq.js.

so far what I have tried:

var data =
            [
                {
                    "ColorCode": "green",
                    "StatusName": "ACTIVE",
                    "rankId": 0,
                    "zone_name": "Zone A",
                    "driver_id": 100,
                    "zone_rank": 1,
                    "status_id": null,
                    "company_id": null,
                    "updated_on": null,
                    "Driver": null,
                    "login_status": null
                },
                {
                    "ColorCode": "yellow",
                    "StatusName": "BREAK",
                    "rankId": 0,
                    "zone_name": "Zone B",
                    "driver_id": 101,
                    "zone_rank": 1,
                    "status_id": null,
                    "company_id": null,
                    "updated_on": null,
                    "Driver": null,
                    "login_status": null
                },
                {
                    "ColorCode": "green",
                    "StatusName": "ACTIVE",
                    "rankId": 0,
                    "zone_name": "Zone A",
                    "driver_id": 102,
                    "zone_rank": 4,
                    "status_id": null,
                    "company_id": null,
                    "updated_on": null,
                    "Driver": null,
                    "login_status": null
                }
            ]

    var zTable = document.getElementById('tblZoneRank');
    var allzones = Enumerable.From(data)
                             .Distinct(p => p.zone_name)
                             .Select(p => p.zone_name).ToArray();

    $.each(allzones, function (i, item) {
    var tr = document.createElement('tr');
    var td = document.createElement("td");
    var txt = document.createTextNode(item);

    td.appendChild(txt);
    tr.appendChild(td);
    var childItem = Enumerable.From(data)
                              .Where(p => p.zone_name == item)
                              .ToArray();
    $.each(childItem, function (j, citem) {
        var ctd = document.createElement("td");
        var ctxt = document.createTextNode(citem.driver_id);

        ctd.appendChild(ctxt);
        $(ctd).css('background-color', citem.ColorCode);
        tr.appendChild(ctd);
    });
    zTable.appendChild(tr);
});

It is giving me output in this way:

<table id="tblZoneRank">
  <tr>
    <td>Zone A</td>
    <td style="background-color: rgb(0, 128, 0);">100</td>
    <td style="background-color: rgb(0, 128, 0);">102</td>
 </tr>
 <tr>
    <td>Zone B</td>
    <td style="background-color: rgb(255, 255, 0);">101</td>
 </tr>
</table>

enter image description here

but I need output in this format: It should display zone_name as column name and underneath driver_id and first id should be zone_rank 1 and 2 and so on.. enter image description here


Solution

  • Am not familiar with linq.js so I used native array method Array#reduce() and Map object to create unique zones

    const $table = $('#zoneTable');
    
    // creates Map object with zone names as keys and arrays of jQuery objects(cells) as values
    const zoneMap = data.reduce((map, item) => {
      const col = map.get(item.zone_name) || [createCell(item.zone_name)];
      col.push(createCell(item.driver_id, item.ColorCode));
      return map.set(item.zone_name, col);
    }, new Map());
    
    // convert Map values to array of arrays. Each sub array is a table column
    const colCells = [...zoneMap.values()];
    
    const totalRows = Math.max(...colCells.map(e => e.length));
    
    for (let i = 0; i < totalRows; i++) {
      const rowCells = colCells.map(col => col[i] || createCell());// fill any missing with empty cell
      const $row = $('<tr>').append(rowCells);
      $table.append($row)
    }
    
    // helper function to create cells
    function createCell(text = '', color = null) {
      const $td = $('<td>').text(text);
      return color ? $td.css('background-color', color) : $td;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table id="zoneTable"></table>
    
    
    <script>
      var data = [{
          "ColorCode": "green",
          "StatusName": "ACTIVE",
          "rankId": 0,
          "zone_name": "Zone A",
          "driver_id": 100,
          "zone_rank": 1,
          "status_id": null,
          "company_id": null,
          "updated_on": null,
          "Driver": null,
          "login_status": null
        },
        {
          "ColorCode": "yellow",
          "StatusName": "BREAK",
          "rankId": 0,
          "zone_name": "Zone B",
          "driver_id": 101,
          "zone_rank": 1,
          "status_id": null,
          "company_id": null,
          "updated_on": null,
          "Driver": null,
          "login_status": null
        },
        {
          "ColorCode": "green",
          "StatusName": "ACTIVE",
          "rankId": 0,
          "zone_name": "Zone A",
          "driver_id": 102,
          "zone_rank": 4,
          "status_id": null,
          "company_id": null,
          "updated_on": null,
          "Driver": null,
          "login_status": null
        }
      ]
    </script>