8

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.

Magesh Kumaar
  • 1,485
  • 2
  • 10
  • 29

2 Answers2

7

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>
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • 1
    Thank you so very much :). That link you had posted was very useful in helping me to understand this solution. – Magesh Kumaar Jul 12 '16 at 18:52
  • https://jsfiddle.net/6xytngz7/ Please take a look at this fiddle. What if I want to avoid duplicate entries like `xxx,xxx` and `unique` them but also maintain the count like `xxx` – Magesh Kumaar Jul 13 '16 at 05:05
  • Please see this question http://stackoverflow.com/questions/38343211/underscore-js-to-filter-out-the-unique-values – Magesh Kumaar Jul 13 '16 at 05:34
  • If we have an empty array in any of child i.e in this case say `"table1": []` table structure breaks. Any idea on how to fix this? – HenonoaH Jun 21 '20 at 17:34
  • @HenonoaH Updated to handle empty arrays for both `"table1": []` and `"buildname1": []` . Essentially the issue was that if the array was empty, it was giving the rowspan value of 0, which treats it as the max it can be. What I did to fix this was to force the minimum rowspan to be 1. Also, I cleaned up the code quite a bit for readability/maintainability. – mhodges Jun 22 '20 at 06:27
  • @mhodges Yes, I too thought to set rowspan. Look's great now. – HenonoaH Jun 22 '20 at 08:44
0


This Question is Little Different and I can't find the answer, First of all, how it Works

  1. Ask for total Row and Column.
  2. Then ask for Rowspan and Colspan for each row and count as a Column.
  3. Total Column is Row*Column Right.
  4. But when we have give that Row as 2 they will occupy another column so they have some logic this code is too many lines but it works.
  5. Lets Have fun and Check out now...

function copytext()
        {
            var output = document.querySelector(".output");
            navigator.clipboard.writeText(output.value);
            alert("Text has been Copied!");
        }
        document.querySelector(".clear").addEventListener("click", () => {
            var output = document.querySelector(".output");
            if(confirm("You want to Clear Code text ?") == true)
            {
                output.innerHTML = "";
            }
        });

        function run()
        {
            var output = document.querySelector(".output");
            var row = parseInt(prompt("Enter Row : "));
            var col = parseInt(prompt("Enter Column : "));

            var col_helps = new Array(row);
            // Assigning Values in Array with columns
            for(var i=0;i<row;i++)
            {
                col_helps[i] = col;
            }
            var loop = 0, count_col = 0;
            var startTag = "", col_newTag = "\n<tr>", onlyOpenTag = "\n<tr>", closeTag = "\n</tr>";
            var checkOpen = 0, all_Count = 0, col_newCheck = 0, check_Zero = 0;

            while(true)
            {
                var row_user = parseInt(prompt("Enter Rowspan User : "));
                var col_user = parseInt(prompt("Enter Colspan User : "));
                var textInsert = prompt("Enter Content to Cell : ");

                if(isNaN(row_user)){ row_user = 1}
                if(isNaN(col_user)){ col_user = 1}

                all_Count = parseInt(all_Count) + (row_user*col_user);
                // Td tag
                var text = "\n<td rowspan=\""+row_user+"\" colspan=\""+col_user+"\">"+textInsert+"</td>";
                var text1 = "\n<td>"+textInsert+"</td>";
                var text2 = "\n<td colspan=\""+col_user+"\">"+textInsert+"</td>";
                var text3 = "\n<td rowspan=\""+row_user+"\">"+textInsert+"</td>";

                // Setting Column Length
                var col_length_of_row = col_helps[loop];

                count_col = parseInt(count_col) + col_user;

                if((col_length_of_row == col) && (col_newCheck == 0))
                {
                    startTag += col_newTag;
                    col_newCheck = 1;
                }

                if(row_user>1)
                {
                    for(var i=loop;i<(loop+(row_user));i++)
                    {
                        if(i!=loop)
                        {
                            col_helps[i] = parseInt(col_helps[i]) - 1;
                        }
                    }
                    if(col_user>1)
                    {
                        for(var i=loop;i<(loop+(row_user));i++)
                        {
                            if(i!=loop)
                            {
                                col_helps[i] = parseInt(col_helps[i]) - (col_user-1);
                            }
                        }
                    }
                }

                if((row_user==1) && (col_user==1))
                {
                    startTag += text1;
                }
                if((row_user!=1) && (col_user!=1))
                {
                    startTag += text;
                }
                if((row_user==1) && (col_user!=1))
                {
                    startTag += text2;
                }
                if((row_user!=1) && (col_user==1))
                {
                    startTag += text3;
                }
                
                if((count_col >= col_length_of_row) && (col_helps[loop+1] == col) && (all_Count < (row*col))){
                    if(checkOpen != 0)
                    {
                        for(var i=0;i<checkOpen;i++)
                        {
                            startTag += closeTag;
                            checkOpen--;
                        }
                    }
                    if(col_newCheck == 1)
                    {
                        startTag += closeTag;
                        col_newCheck = 0;
                    }

                    for(var i=loop;i<row;i++)
                    {
                        if(col_helps[loop+1] != 0)
                        {
                            loop++;
                            break;
                        }
                        if(col_helps[loop+1] == 0)
                        {
                            check_Zero = 1;
                        }
                    }
                    if(check_Zero == 1)
                    {
                        startTag += closeTag;
                        check_Zero = 0;
                    }
                    count_col = 0;
                }

                if((count_col >= col_length_of_row) && (col_helps[loop+1] != col) && (all_Count < (row*col))){
                    if(checkOpen != 0)
                    {
                        for(var i=0;i<checkOpen;i++)
                        {
                            startTag += closeTag;
                            checkOpen--;
                        }
                    }

                    startTag += onlyOpenTag;
                    checkOpen++;
                    for(var i=loop;i<row;i++)
                    {
                        if(col_helps[loop+1] != 0)
                        {
                            loop++;
                            break;
                        }
                        if(col_helps[loop+1] == 0)
                        {
                            check_Zero = 1;
                        }
                    }

                    if(check_Zero == 1)
                    {
                        startTag += closeTag;
                        check_Zero = 0;
                    }
                    count_col = 0;
                }

                if(all_Count >= (row*col))
                {
                    if(checkOpen != 0)
                    {
                        for(var i=0;i<checkOpen;i++)
                        {
                            startTag += closeTag;
                            checkOpen--;
                        }
                    }
                    startTag += closeTag;
                    output.innerHTML = startTag.trim();
                    break;
                }
            }
        }
*{
            padding: 0;
            margin: 0;
        }
        .container{
            position: relative;
            display: flex;
            flex-direction: column;
            min-height: 100vh;
            justify-content: center;
            align-items: center;
            background-color: indigo;
        }
        .output{
            height: 400px;
            min-width: 300px;
            min-height: 400px;
            width: 500px;
            max-height: 450px;
            max-width: 500px;
            background-color: #eee;
            box-sizing: border-box;
            padding: 10px;
            color: black;
            font-weight: 600;
            border-radius: 5px;
        }
        .create{
            box-sizing: border-box;
            padding: 6px;
            margin: 5px;
            background-color: yellow;
            font-weight: 600;
            font-size: 14px;
        }
        .clear{
            box-sizing: border-box;
            padding: 6px;
            margin: 5px;
            background-color: red;
            color: white;
            font-weight: 600;
            font-size: 14px;
        }
        .copy{
            box-sizing: border-box;
            padding: 6px;
            margin: 5px;
            background-color: black;
            color: white;
            font-weight: 600;
            font-size: 14px;
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Table</title>
</head>
<body>
    
    <div class="container">
        <p>
            <button onclick="run()" class="create">Create Row</button>
            <button class="clear">Clear Content</button>
        </p>
        <textarea class="output" disabled></textarea>
        <button onclick="copytext()" class="copy">Copy Code</button>
    </div>

</body>
</html>
  • If you have a new question, please ask it by clicking the [Ask Question](https://stackoverflow.com/questions/ask) button. Include a link to this question if it helps provide context. - [From Review](/review/late-answers/32503585) – treckstar Aug 23 '22 at 00:17