Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic & Complex rowspan in HTML table

Link to JSFiddle

Here is my JSON format

{
    "result": {
        "buildname1": [{
            "table1": ["xxx","yyy"]
        }, {
            "table2": ["xxx","yyy"]
        }, {
            "table3": ["xxx","yyy"]
        }],
        "buildname2": [{
            "table1": ["xxx","yyy"]
        }, {
            "table2": ["xxx","yyy"]
        }, {
            "table3": ["xxx","yyy"]
        }]
    },
    "Build sets": "yyy",
    "destinationPath": "xxx",
    "status": 1
}

This is the function which I am using to dynamically create the table.

function generateTable(data){ //data is the parsed JSON Object from an ajax request
    $("#test-table tbody").empty();//Empty the table first
    if(data.result != null){
        $.each(data.result,function(key,value){
            var buildName ="<tr><td rowspan='"+value.length+"'>"+key+"<span class='cyan darken-1 white-text badge'>"+value.length+" base tables</span></td>";
            var baseTable ="";
            for(i=0;i<value.length;i++){
                if( i == 0 ){
                    for(var k in value[0]){
                        baseTable ="<td rowspan='"+value[0][k].length+"'>"+k+"</td></tr>";
                    }
                }
                else{
                    for(var key in value[i]){
                        baseTable = baseTable + "<tr><td rowspan='"+value[i][key].length+"'>"+key+"</td></tr>";
                    }
                }
            }
            $("#test-table").append(buildName + baseTable);
        });
    }
}

Here is what I am trying to achieve

enter image description here

HTML

<table id="test-table" class="bordered responsive-table">
  <thead>
    <tr>
      <th>Build Name</th><th>Base Table</th><th>Query List</th>
    </tr>
  </thead>
</table>

Question :

I successfully created the first two columns(though somewhat ugly, thought I can refine it later), I'm stuck at the third column. The code I posted creates the first two columns correctly but the logic for the rowspan within the rowspan(third column) seems to elude me. Please guide me.

like image 947
Magesh Kumaar Avatar asked Jul 12 '16 13:07

Magesh Kumaar


1 Answers

I honestly had never used rowspan before, but after reading this stack answer I understood it much better - I would highly recommend you do the same. After that, it was just a matter of figuring out the order of the elements from JSON into the DOM.

Here is a WORKING DEMO:

var data = '{"result":{"buildname1":[{"table1":["xxx","yyy", "zzz"]},{"table2":["xxx","yyy"]}],"buildname2":[{"table1":["xxx","yyy", "zzz"]},{"table2":["xxx","yyy"]},{"table3":["xxx","yyy"]}], "buildname3":[{"table1":[]},{"table2":["xxx","yyy"]},{"table3":[]}], "buildname4":[]},"Build sets":"yyy","destinationPath":"xxx","status":1}';

function generateTable(data) { //data is the parsed JSON Object from an ajax request
  data = JSON.parse(data);
  $("#test-table tbody").empty(); //Empty the table first
  Object.entries(data.result).forEach(([key, elem]) => {
    var baseHtml = "";
    var childrenHtml = "";
    var maxRowSpan = 0;
    elem.forEach((inner_elem, index) => {
      var [innerElemKey, arr] = Object.entries(inner_elem)[0];
      var elemRowSpan = Math.max(arr.length, 1);
      maxRowSpan += elemRowSpan;

      if (index !== 0) {
        childrenHtml += "<tr>";
      } 
      childrenHtml += ('<td rowspan="' + elemRowSpan + '">' + innerElemKey + '</td>');
      
      arr.forEach((child, indx) => {
        if (indx !== 0) {
          childrenHtml += "</tr>";
        }
        childrenHtml += ('<td rowspan="1">' + child + '</td>' + '</tr>');
      });
    });
    baseHtml += ('<tr><td rowspan="' + Math.max(maxRowSpan, 1) + '">' + key + '</td>');
    $("#test-table").append(baseHtml + childrenHtml);
  });
}

$(function() {
  generateTable(data);
});
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test-table" class="bordered responsive-table">
  <thead>
    <tr>
      <th>Build Name</th>
      <th>Base Table</th>
      <th>Query List</th>
    </tr>
  </thead>
</table>

#Static HTML

<table id="test-table" class="bordered responsive-table">
  <thead>
    <tr>
      <th>Build Name</th><th>Base Table</th><th>Query List</th>
    </tr>
  </thead>
</table>

#Generated HTML

<table id="test-table" class="bordered responsive-table">
  <thead>
    <tr>
      <th>Build Name</th>
      <th>Base Table</th>
      <th>Query List</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="5">buildname1</td>
      <td rowspan="3">table1</td>
      <td rowspan="1">xxx</td>
    </tr>
    <tr>
      <td rowspan="1">yyy</td>
    </tr>
    <tr>
      <td rowspan="1">zzz</td>
    </tr>
    <tr>
      <td rowspan="2">table2</td>
      <td rowspan="1">xxx</td>
    </tr>
    <tr>
      <td rowspan="1">yyy</td>
    </tr>
    <tr>
      <td rowspan="7">buildname2</td>
      <td rowspan="3">table1</td>
      <td rowspan="1">xxx</td>
    </tr>
    <tr>
      <td rowspan="1">yyy</td>
    </tr>
    <tr>
      <td rowspan="1">zzz</td>
    </tr>
    <tr>
      <td rowspan="2">table2</td>
      <td rowspan="1">xxx</td>
    </tr>
    <tr>
      <td rowspan="1">yyy</td>
    </tr>
    <tr>
      <td rowspan="2">table3</td>
      <td rowspan="1">xxx</td>
    </tr>
    <tr>
      <td rowspan="1">yyy</td>
    </tr>
  </tbody>
</table>
like image 132
mhodges Avatar answered Oct 14 '22 18:10

mhodges