代码之家  ›  专栏  ›  技术社区  ›  dawncode

从JSON数据动态生成HTML表

  •  0
  • dawncode  · 技术社区  · 6 年前

    我需要动态生成HTML表并在下面列出驱动程序ID。 它类似于Pivot,但问题是Zone名称每天都会更改。 我正在使用jquery和linq.js。

    到目前为止,我已经尝试了:

    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);
    });
    

    它以这种方式给我输出:

    <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

    但我需要这种格式的输出: 它应该将区域名称显示为列名称,并在驱动程序ID下面,第一个ID应该是区域级别1和2,依此类推。 enter image description here

    2 回复  |  直到 6 年前
        1
  •  0
  •   charlietfl    6 年前

    不熟悉linq.js,所以我使用了本机数组方法 Array#reduce() Map 创建唯一区域的对象

    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>
        2
  •  1
  •   Jeff Mercado    5 年前

    因此,根据我从您的问题中收集到的信息,您试图按区域对数据项进行分组,然后将它们输出到一个表中,其中的列是区域。linq.js可以很好地处理这个问题,只是在将数据行转置为列时遇到了一些问题。

    const zTable = $('#tblZoneRank');
    const rows = Enumerable.From(data)
      .GroupBy(p => p.zone_name, p =>
        $('<td></td>')
          .css({'background-color': p.ColorCode})
          .text(p.driver_id)
      )
      .Let(buildRows)
      .Select(rs =>
        $('<tr></tr>').append(rs)
      );
    rows.ForEach(r => r.appendTo(zTable));
    
    function buildRows(gs) {
      const header = gs.Select(g =>
        $('<th></th>').text(g.Key())
      ).ToArray();
      const rows = Enumerable.RepeatWithFinalize(
          () => gs.Select(g => g.GetEnumerator()).ToArray(),
          es => es.forEach(e => e.Dispose())
        )
        .Select(es => es.map(e => [e.MoveNext(), e.Current()]))
        .TakeWhile(xs => xs.reduce((a, x) => a || x[0], false))
        .Select(xs => xs.map(x => x[0] ? x[1] : $('<td></td>')));
      return Enumerable.Return(header).Concat(rows);
    }