1

I need to use css and dynamically create a table with the JSON array.

Something like this : Here I have just passed the cell to be spanned a class of 'spannedrow' , I don't have the class yet. This is just a sample. I need help in doing such class.

var div="<div>";
    for(var i=0;i<myArr.length;i++) {     
        var arrHobies = myArr[i]['Hobbies'];
        var arrSkills = myArr[i]['Skills'];
        var arrLanguage = myArr[i]['Language'];
         div+="<div>";
         div+="<div class='spannedrow'>"+myArr[i]['Id']+"</td>";
         div+="<div class='spannedrow'>"+myArr[i]['Name']+"</td>";
         div+="<div class='spannedrow'>"+myArr[i]['Age']+"</td>";
         for(var j=0;j<arrHobies.length;j++ ) {
              div+="<div class='singlerow'>"+arrHobies[j]['HobbyId']+"</td>";
              div+="<div class='singlerow'>"+arrHobies[j]['HobbyName']+"</td>";
         }
          for(var l=0;l<arrSkills.length;l++ ) {
              div+="<div class='singlerow'>"+arrSkills[l]['SkillId']+"</td>";
              div+="<div class='singlerow'>"+arrSkills[l]['SkillName']+"</td>";
         }
         var div+="</div>"
    }
var div+="</div>" ;  

And my array is something like below .

var myArr = [{
    "Id": 1,
    "Name": 'Ken',
    "Age": '30',
    "Hobbies": [{
      'HobbyId': 1,
      'HobbyName': 'Swimming'
    }, {
      'HobbyId': 2,
      'HobbyName': 'Reading'
    }],
    "Skills": [{
      'SkillId': 1,
      'SkillName': 'PHP'
    }, {
      'SkillId': 2,
      'SkillName': 'MySQL'
    }],
    "Language": [{
      'LangId': 2,
      'LangName': 'English'
    }, {
      'LangId': 3,
      'LangName': 'Chinese'
    }]
  },
  {
    "Id": 2,
    "Name": 'Mike',
    "Age": '20',
    "Hobbies": [],
    "Skills": [],
    "Language": []
  },
  {
    "Id": 3,
    "Name": 'Charlie',
    "Age": '25',
    "Hobbies": [{
      'HobbyId': 5,
      'HobbyName': 'Dance'
    }, {
      'HobbyId': 6,
      'HobbyName': 'Sing'
    }, {
      'HobbyId': 7,
      'HobbyName': 'Writing'
    }],
    "Skills": [],
    "Language": [{
      'Id': 7,
      'Name': 'English'
    }]
  }
]

My table with the below array will then look like this

Is there a way I can do this with css styling to span rows?

I am adding some real dynamic data.

 var myArr = [
            {
                "ItemMasterNumber":"290015","IM_Description":"XXX5","IM_FirstProcessDate":"10-19-2016",
                "IM_Alias":"test"                
                "ItemFeatureSet":
                        [{"FS_Id":"2002","FS_Code":"XXX5","FS_Name":"XXX5","FS_Description":"XXX5"}],
                "ItemFeatures":
                      [{"FE_Id":"1864","FE_Value":"VERSION","FE_Name":"2017"},
                       {"FE_Id":"1865","FE_Value":"EDITION","FE_Name":"Deluxe"}],
                "ItemCharges":[
                    {"CH_ChargeId":"23004746","CH_Name":"XXX5","CH_Description":"",
                        "CH_Type":"One Time"
                     }],
                "ItemChargeAttributes":[
                         {"CA_Id":"1628","CA_ListPrice":"99","CA_FairValueBasis":"BESP"}],
                "ItemPackages":[{"PA_PackageId":"21004482"}],
                "ItemPackagesComponents":[{"PA_Id":"9189","PA_Type":"Feature Set"},{"PA_Id":"9190","PA_Type":"Charge"}],
                "ItemOffers":[{"OF_OfferId":"20003880","OF_Name":"XXX5"}],
                "ItemOffersComponents":[{"OC_Id":"3877","OC_Quantity":"","OC_AdjustmentAmount":""}]
            }];

With above real array I tried the below code but is mixing up some data.

<html>
  <head>
    <title>TODO supply a title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script>
        $( document ).ready(function() {
        var myArr = [
            {
                "ItemMasterNumber":"290015","IM_Description":"XXX5","IM_FirstProcessDate":"10-19-2016",
                "IM_Alias":"test"                
                "ItemFeatureSet":
                        [{"FS_Id":"2002","FS_Code":"XXX5","FS_Name":"XXX5","FS_Description":"XXX5"}],
                "ItemFeatures":
                      [{"FE_Id":"1864","FE_Value":"VERSION","FE_Name":"2017"},
                       {"FE_Id":"1865","FE_Value":"EDITION","FE_Name":"Deluxe"}],
                "ItemCharges":[
                    {"CH_ChargeId":"23004746","CH_Name":"XXX5","CH_Description":"",
                        "CH_Type":"One Time"
                     }],
                "ItemChargeAttributes":[
                         {"CA_Id":"1628","CA_ListPrice":"99","CA_FairValueBasis":"BESP"}],
                "ItemPackages":[{"PA_PackageId":"21004482"}],
                "ItemPackagesComponents":[{"PA_Id":"9189","PA_Type":"Feature Set"},{"PA_Id":"9190","PA_Type":"Charge"}],
                "ItemOffers":[{"OF_OfferId":"20003880","OF_Name":"XXX5"}],
                "ItemOffersComponents":[{"OC_Id":"3877","OC_Quantity":"","OC_AdjustmentAmount":""}]
            }];
console.log(JSON.stringify(myArr));
// Assuming it's not going to be empty
var headers = ["Item Number", "Description", "First Process Date", "Alias", "Master Price", "Product Id", "Product Description",
    "FeatureSet #","Feature Set Code","Name","Description","Enablement Type",
    "Feature Id","Value","Name",
    "Charge Id","Name","Description","Type",
     "Record Id","List Price","Fair Value Basis","Fair Value Low","Fair Value High","Effective SD",
    "Package Id",
    "Record Id","Component Type",
    "Offer Id","Name","Description","Type","Level","Effective SD",
    "Record Id","Quantity","Adjustment Amt"

    ];

var containers = ["ItemFeatureSet", "ItemFeatures", "ItemCharges",
    "ItemChargeAttributes",
    "ItemPackages","ItemPackagesComponents","ItemOffers",
    "ItemOffersComponents"];

for (let header of headers)
{
    console.log('Ok');
    console.log('${header}')
  $("#headers").append(`<th>${header}</th>`);
}

// foreach item
for (let group of myArr)
{
  let span = 1;

  // Sets the length of row span
  for (let container of containers)
  {
    span = group[container].length > span ? group[container].length : span;
  }

  // for the first/main row of each item
  let temp_tr = $("<tr>");
  for (let item in group)
  {
    // Checking if key is array
    if (Array.isArray(group[item]))
    {
      let insert_value = "";
      //If it is greater than 0 use value
      if (group[item].length)
      {
        let temp_keys = Object.keys(group[item][0]);
        for (let tk of temp_keys)
        {
          insert_value += `<td>${group[item][0][tk]}</td>`;
        }
      }
      else
      {
        insert_value += "<td></td><td></td>";
      }

      $(temp_tr).append(insert_value);
    }
    else
    {
      $(temp_tr).append(`<td rowspan=${span}>${group[item]}</td>`);
    }

  }
  // Add to tbody
  $("#body").append(temp_tr); 


  // for each inner item
  for (let i = 1; i < span; i++)
  {
    let temp_tr = $("<tr>");

    for (let item of containers)
    {
      let insert_value = "";

      // Only add values if there are any
      if (i < group[item].length)
      {
        let temp_keys = Object.keys(group[item][i]);
        for (let tk of temp_keys)
        {
          insert_value += `<td>${group[item][i][tk]}</td>`;
        }
      }
      else
      {
        insert_value += "<td></td><td></td>";
      }
      $(temp_tr).append(insert_value);  
      $("#body").append(temp_tr);
    }

  }


}
 });
    </script>
  </head>
  <body>
      <table id="mytable" border=1>
  <thead>
    <tr>
      <th colspan=7></th>
      <th colspan=5>Feature Set Related Data</th>
      <th colspan=3>Features Related Data</th>
      <th colspan=4>Charges Related Data</th>
      <th colspan=6>Charge Attribute Related Data</th>
      <th colspan=1>Package Related Info</th>
      <th colspan=2>Package Component Related Data</th>
      <th colspan=6>Offer Related Data</th>
      <th colspan=3>Offers Component Related Data</th>
    </tr>
    <tr id="headers">
    </tr>
  </thead>
  <tbody id="body">
  </tbody>
</table>
  </body>
</html>
4
  • what do you mean by "span rows" aren't you doing that already? Commented Apr 27, 2017 at 4:30
  • why not use HTML table for this? It's just much simpler. Unless you want to animate your cells. Commented Apr 27, 2017 at 4:32
  • @A.Lau I have json array of which I want to get the look as in the image I shared.Currently just for the sake of the example I have passed a class to div. Commented Apr 27, 2017 at 4:37
  • @KingKing I am facing an issue with that as the number of elements in the subarrays can vary. But if you can share the way it should be implemented with HTML table would be really helpful. Commented Apr 27, 2017 at 4:39

2 Answers 2

0

Here's my answer. Let me know what you don't understand. I'm probably missing some validation somewhere... but I think it's a good start. And just play around with border css to get what you want.

var myArr = [{
    "Id": 1,
    "Name": 'Ken',
    "Age": '30',
    "Hobbies": [{
      'HobbyId': 1,
      'HobbyName': 'Swimming'
    }, {
      'HobbyId': 2,
      'HobbyName': 'Reading'
    }],
    "Skills": [{
      'SkillId': 1,
      'SkillName': 'PHP'
    }, {
      'SkillId': 2,
      'SkillName': 'MySQL'
    }],
    "Language": [{
      'LangId': 2,
      'LangName': 'English'
    }, {
      'LangId': 3,
      'LangName': 'Chinese'
    }]
  },
  {
    "Id": 2,
    "Name": 'Mike',
    "Age": '20',
    "Hobbies": [],
    "Skills": [],
    "Language": []
  },
  {
    "Id": 3,
    "Name": 'Charlie',
    "Age": '25',
    "Hobbies": [{
      'HobbyId': 5,
      'HobbyName': 'Dance'
    }, {
      'HobbyId': 6,
      'HobbyName': 'Sing'
    }, {
      'HobbyId': 7,
      'HobbyName': 'Writing'
    }],
    "Skills": [],
    "Language": [{
      'Id': 7,
      'Name': 'English'
    }]
  }
];

// Assuming it's not going to be empty
var headers = ["Id", "Name", "Age", "HobbyId", "HobbyName", "SkillId", "SkillName", "Id", "Name"];

var containers = ["Hobbies", "Skills", "Language"];

for (let header of headers)
{
  $("#headers").append(`<th>${header}</th>`);
}

// foreach item
for (let group of myArr)
{
  let span = 1;
  
  // Sets the length of row span
  for (let container of containers)
  {
    span = group[container].length > span ? group[container].length : span;
  }
  
  // for the first/main row of each item
  let temp_tr = $("<tr>");
  for (let item in group)
  {
    // Checking if key is array
    if (Array.isArray(group[item]))
    {
      let insert_value = "";
      //If it is greater than 0 use value
      if (group[item].length)
      {
        let temp_keys = Object.keys(group[item][0]);
        for (let tk of temp_keys)
        {
          insert_value += `<td>${group[item][0][tk]}</td>`;
        }
      }
      else
      {
        insert_value += "<td></td><td></td>";
      }
      
      $(temp_tr).append(insert_value);
    }
    else
    {
      $(temp_tr).append(`<td rowspan=${span}>${group[item]}</td>`);
    }

  }
  // Add to tbody
  $("#body").append(temp_tr); 
  
  
  // for each inner item
  for (let i = 1; i < span; i++)
  {
    let temp_tr = $("<tr>");
    
    for (let item of containers)
    {
      let insert_value = "";

      // Only add values if there are any
      if (i < group[item].length)
      {
        let temp_keys = Object.keys(group[item][i]);
        for (let tk of temp_keys)
        {
          insert_value += `<td>${group[item][i][tk]}</td>`;
        }
      }
      else
      {
        insert_value += "<td></td><td></td>";
      }
      $(temp_tr).append(insert_value);  
      $("#body").append(temp_tr);
    }
    
  }

  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="mytable" border=1>
  <thead>
    <tr>
      <th colspan=3></th>
      <th colspan=2>Hobbies</th>
      <th colspan=2>Skills</th>
      <th colspan=2>Language</th>
    </tr>
    <tr id="headers">
    </tr>
  </thead>
  <tbody id="body">
  </tbody>
</table>

Sign up to request clarification or add additional context in comments.

7 Comments

Seems the code is nice and dynamic but doesn't seems to run for me.I can only see the table with just the column headings.Am not sure why is it not running for me.
@Alau Hey I tried with my dynamic array and its failing there.
how so "failing"
Its mixing up the values.I have shared the real data if you can have a look over it.
That's pretty much completely different to the example you gave. My code isn't that dynamically robust, as what you want is actually quite difficult even from the example given. I could probably make something work, but I'm not going to do the top most header, i.e. Hobbies, Skills, Language part.
|
0

You can try table structure like,

var myArr = [{
    "Id": 1,
    "Name": 'Ken',
    "Age": '30',
    "Hobbies": [{
      'HobbyId': 1,
      'HobbyName': 'Swimming'
    }, {
      'HobbyId': 2,
      'HobbyName': 'Reading'
    }],
    "Skills": [{
      'SkillId': 1,
      'SkillName': 'PHP'
    }, {
      'SkillId': 2,
      'SkillName': 'MySQL'
    }],
    "Language": [{
      'LangId': 2,
      'LangName': 'English'
    }, {
      'LangId': 3,
      'LangName': 'Chinese'
    }]
  },
  {
    "Id": 2,
    "Name": 'Mike',
    "Age": '20',
    "Hobbies": [],
    "Skills": [],
    "Language": []
  },
  {
    "Id": 3,
    "Name": 'Charlie',
    "Age": '25',
    "Hobbies": [{
      'HobbyId': 5,
      'HobbyName': 'Dance'
    }, {
      'HobbyId': 6,
      'HobbyName': 'Sing'
    }, {
      'HobbyId': 7,
      'HobbyName': 'Writing'
    }],
    "Skills": [],
    "Language": [{
      'LangId': 7,
      'LangName': 'English'
    }]
  }
];

function getRows(obj,maxRow,id,name){
  var div='';
  if (obj.length || maxRow) {
      div += "<table>";
      obj.length && $(obj).each(function() {
      
          div += '<tr><td width="40%">' + this[id] + '</td><td width="60%">' + this[name] + '</td></tr>';
      });
      if(obj.length<maxRow){
        for(var i=0,l=maxRow-obj.length;i<l;i++){
          div += '<tr><td width="40%">&nbsp;</td><td  width="60%">&nbsp;</td></tr>';
        }
      }
      div += '</table>';
    }
    return div;
}


var div = "<table border='1' style='border:1px solid #000;' cellpadding='0' cellspacing='0' >";
div += '<tr><td colspan="3"></td>' +
  '<td>Hobbies</td><td>Skills</td><td>Languages</td></tr>';
div += '<tr><td>Id</td><td>Name</td><td>Age</td>' +
  '<td><table><tr><td width="40%">Hobby Id</td><td  width="60%">Hobby Name</td></tr></table>'+
  '<td><table><tr><td width="40%">Skill Id</td><td  width="60%">Skill Name</td></tr></table>'+
  '<td><table><tr><td width="40%">Language Id</td><td  width="60%">Language Name</td></tr></table>';
for (var i = 0; i < myArr.length; i++) {
  var arrHobies = myArr[i]['Hobbies'];
  var arrSkills = myArr[i]['Skills'];
  var arrLanguage = myArr[i]['Language'];
  var maxRow=Math.max(arrHobies.length,arrSkills.length,arrLanguage.length);
  div += "<tr>";
  div += "<td valign='top' class='pad-5'>" + myArr[i]['Id'] + "</td>";
  div += "<td valign='top' class='pad-5'>" + myArr[i]['Name'] + "</td>";
  div += "<td valign='top' class='pad-5'>" + myArr[i]['Age'] + "</td>";
  div += '<td>'+
          getRows(arrHobies,maxRow,'HobbyId','HobbyName')+
          '</td>';
  div += '<td>'+
          getRows(arrSkills,maxRow,'SkillId','SkillName')+
          '</td>';
  div += '<td>'+
          getRows(arrLanguage,maxRow,'LangId','LangName')+
          '</td>'; 
  div += "</tr>"
}
div += "</table>";
$(div).appendTo('body');
table {
  border-collapse:collapse;
  width:100%;
}
table table td {
  border: 1px solid black;
  padding:5px;

}
.pad-5{padding:5px}
table table tr:first-child td {
  border-top: 0;
}
table table tr:last-child td {
  border-bottom: 0;
}
table table tr td:first-child {
  border-left: 0;
}
table table tr td:last-child{
  border-right: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Updated for dynamic data,

var myArr = [{
            "ItemMasterNumber": "290015",
            "IM_Description": "XXX5",
            "IM_FirstProcessDate": "10-19-2016",
            "IM_Alias": "test",
            "ItemFeatureSet": [{
                "FS_Id": "2002",
                "FS_Code": "XXX5",
                "FS_Name": "XXX5",
                "FS_Description": "XXX5"
            }],
            "ItemFeatures": [{
                "FE_Id": "1864",
                "FE_Value": "VERSION",
                "FE_Name": "2017"
            },
            {
                "FE_Id": "1865",
                "FE_Value": "EDITION",
                "FE_Name": "Deluxe"
            }
            ],
            "ItemCharges": [{
                "CH_ChargeId": "23004746",
                "CH_Name": "XXX5",
                "CH_Description": "",
                "CH_Type": "One Time"
            }],
            "ItemChargeAttributes": [{
                "CA_Id": "1628",
                "CA_ListPrice": "99",
                "CA_FairValueBasis": "BESP"
            }],
            "ItemPackages": [{
                "PA_PackageId": "21004482"
            }],
            "ItemPackagesComponents": [{
                "PA_Id": "9189",
                "PA_Type": "Feature Set"
            }, {
                "PA_Id": "9190",
                "PA_Type": "Charge"
            }],
            "ItemOffers": [{
                "OF_OfferId": "20003880",
                "OF_Name": "XXX5"
            }],
            "ItemOffersComponents": [{
                "OC_Id": "3877",
                "OC_Quantity": "",
                "OC_AdjustmentAmount": ""
            }]
        },{
  "ItemMasterNumber": "290015",
  "IM_Description": "XXX5",
  "IM_FirstProcessDate": "10-19-2016",
  "IM_Alias": "test",
  "ItemFeatureSet": [{
    "FS_Id": "2002",
    "FS_Code": "XXX5",
    "FS_Name": "XXX5",
    "FS_Description": "XXX5"
  }],
  "ItemFeatures": [{
      "FE_Id": "1864",
      "FE_Value": "VERSION",
      "FE_Name": "2017"
    },
    {
      "FE_Id": "1865",
      "FE_Value": "EDITION",
      "FE_Name": "Deluxe"
    }
  ],
  "ItemCharges": [{
    "CH_ChargeId": "23004746",
    "CH_Name": "XXX5",
    "CH_Description": "",
    "CH_Type": "One Time"
  }],
  "ItemChargeAttributes": [{
    "CA_Id": "1628",
    "CA_ListPrice": "99",
    "CA_FairValueBasis": "BESP"
  }],
  "ItemPackages": [{
    "PA_PackageId": "21004482"
  }],
  "ItemPackagesComponents": [{
    "PA_Id": "9189",
    "PA_Type": "Feature Set"
  }, {
    "PA_Id": "9190",
    "PA_Type": "Charge"
  }],
  "ItemOffers": [{
    "OF_OfferId": "20003880",
    "OF_Name": "XXX5"
  }],
  "ItemOffersComponents": [{
    "OC_Id": "3877",
    "OC_Quantity": "",
    "OC_AdjustmentAmount": ""
  }]
}];
var table = '<table border="1"><tr>',
        tblArray=[],
        isFirstRow = true;

        for (var i = 0, cols = Object.keys(myArr[0]), l = cols.length; i < l; i++) {
            table += '<th>' + cols[i] + '</th>';
        };
        table += '</tr>';

        tblArray.push(table);
        $.each(myArr, function(index, myObj) {
            table = '<tr>';

            $.each(myObj, function(key, data) {
                isFirstRow = !index;
                if ($.isArray(data)) {
                    if (isFirstRow) {
                        table += '<td><table><tr>';

                        for (var i = 0, cols = Object.keys(data[0]), l = cols.length; i < l; i++) {
                            table += '<th>' + cols[i] + '</th>';
                        }
                        table += '</tr>';
                        isFirstRow=false;
                    } else {
                        table += '<td><table>';
                    }               
                    $.each(data, function(k, val) {
                        table += '<tr>';
                        $.each(val, function(j, v) {
                            table += '<td> ' + v + ' </td>';
                        });
                        table += '</tr>';
                    });
                    table += '</table></td>';
                } else {
                    data = data.trim().length==0 ? '&nbsp;':data;
                    table += '<td> ' + data + ' </td>';
                }


            });
            isFirstRow = false;
            table += '</tr>';
            tblArray.push(table);
        });

        $(tblArray.join()).appendTo('body');

        $('table th').each(function(){
            $(this).text(function(){
                return $(this).text().replace(/([A-Z])/g, ' $1').replace('_',' ')
                // uppercase the first character
                .replace(/^./, function(str){ return str.toUpperCase(); })
        });
    });
table {
  border-collapse: collapse;
  width: 100%;
}

table table td,
table table th {
  border: 1px solid black;
}

.pad-5 {
  padding: 5px
}

table table tr:first-child td,
table table tr:first-child th {
  border-top: 0;
}

table table tr:last-child td,
table table tr:last-child th {
  border-bottom: 0;
}

table table tr td:first-child,
table table tr th:first-child {
  border-left: 0;
}

table table tr td:last-child,
table table tr th:last-child {
  border-right: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

7 Comments

missing a bit from his image
no, you're missing a row, and your ids aren't lining up as though they're the same column
@RohanKumar you are passing in getRows fixed elements like Id and Name, I might have a lot other columns too.
@Sonali you can make it dynamic. In my answer you have got some idea, how to create a table from JSON data. Also, if you are unable to do, then add a new question or edit your question with new data.
@RohanKumar, added some real data.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.