最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Build a table with row and column spans for my JSON - Stack Overflow

programmeradmin1浏览0评论

I wanted to achieve similar result as shown in below image

Expected result:

what I'm expecting is if it is done using recursion most wele

I will recieve huge json from backend with user_data having 50 objects

Note:recursive approach is most wele

here is what I have tried:

var data = [{
  "user_data": [{
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "hulk"
}, {
  "user_data": [ {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "gomu"
}];

var tableStr = '';
data.forEach((obj) => {
   var userData = obj.user_data;
   userData.forEach((o) => {
      tableStr += '<tr rowspan="'+userData.length+'"><td>'+o.time1+'</td><td>'+o.time2+'</td><td>'+o.amount+'</td></tr>';
   });
});

$('#user').html(tableStr);
table { 
       border-collapse: collapse;
   }

td {
    padding: 20px; 
    border: 1px solid black; 
    text-align: center;
}
<script src=".1.1/jquery.min.js"></script>
<table id="user">
    <thead>
        <tr>
          <th>User Name</th>
          <th>Time 1</th>
          <th>Time 2</th>
          <th>Amount</th>
        </tr>
    </thead>
    <tbody>
      
    </tbody>
</table>

I wanted to achieve similar result as shown in below image

Expected result:

what I'm expecting is if it is done using recursion most wele

I will recieve huge json from backend with user_data having 50 objects

Note:recursive approach is most wele

here is what I have tried:

var data = [{
  "user_data": [{
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "hulk"
}, {
  "user_data": [ {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "gomu"
}];

var tableStr = '';
data.forEach((obj) => {
   var userData = obj.user_data;
   userData.forEach((o) => {
      tableStr += '<tr rowspan="'+userData.length+'"><td>'+o.time1+'</td><td>'+o.time2+'</td><td>'+o.amount+'</td></tr>';
   });
});

$('#user').html(tableStr);
table { 
       border-collapse: collapse;
   }

td {
    padding: 20px; 
    border: 1px solid black; 
    text-align: center;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="user">
    <thead>
        <tr>
          <th>User Name</th>
          <th>Time 1</th>
          <th>Time 2</th>
          <th>Amount</th>
        </tr>
    </thead>
    <tbody>
      
    </tbody>
</table>

Share Improve this question edited Aug 1, 2018 at 19:15 Salman Arshad 273k84 gold badges444 silver badges534 bronze badges asked Aug 1, 2018 at 17:07 EaBengaluruEaBengaluru 892 gold badges30 silver badges73 bronze badges 7
  • 1 There's no need for recursion for this. You can do it by iterating the "user_data" array. – Niche Commented Aug 1, 2018 at 17:18
  • ok thanks for suggestion , but result is not ing as expected with total please help me – EaBengaluru Commented Aug 1, 2018 at 17:20
  • 1 because you didn't implement total functionality – Observer Commented Aug 1, 2018 at 17:22
  • actually i don't know i'm still in learning phase – EaBengaluru Commented Aug 1, 2018 at 17:25
  • Note (in my answer below) how a couple of extra calculations allows you to change the amount of fields in "user_data" and still format the table correctly. No need for recursion. – Niche Commented Aug 1, 2018 at 17:39
 |  Show 2 more ments

4 Answers 4

Reset to default 3

This can be achieved with some slight modifications to your code. You need to add the name with a colspan, then in the obj loop, add a total at the end. Then when updating your table, only set the html for the tbody element. Like below

var data = [{
  "user_data": [{
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "hulk"
}, {
  "user_data": [ {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "gomu"
}];

var tableStr = '';
data.forEach((obj) => {
    var userData = obj.user_data;
    var total = 0;
   
    userData.forEach((o, index) => {
      tableStr += '<tr>' + (index == 0 ? '<td rowspan="' + userData.length + '">' + obj.name + '</td>' : '') + '<td>'+o.time1+'</td><td>'+o.time2+'</td><td>'+o.amount+'</td></tr>';
       total += o.amount;
   });
   tableStr += '<tr><td colspan="3">Total</td><td>' + total + '</td></tr>';
});
$('#user tbody').html(tableStr);
table { 
       border-collapse: collapse;
   }

td {
    padding: 20px; 
    border: 1px solid black; 
    text-align: center;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="user">
    <thead>
        <tr>
          <th>User Name</th>
          <th>Time 1</th>
          <th>Time 2</th>
          <th>Amount</th>
        </tr>
    </thead>
    <tbody>
      
    </tbody>
</table>

I would rather not build a string. Instead use jQuery DOM functions to generate the table:

var data = [{
  "user_data": [{
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "hulk"
}, {
  "user_data": [{
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "gomu"
}];

data.forEach(function(row) {
  var user0 = row.user_data[0];
  var users = row.user_data.slice(1);
  var total = 0;

  // first row of the group contains user name and first user_data
  total += user0.amount;
  var $tr = $("<tr></tr>");
  $("<td></td>").attr("rowspan", 1 + users.length).text(row.name).appendTo($tr);
  $("<td></td>").text(user0.time1).appendTo($tr);
  $("<td></td>").text(user0.time2).appendTo($tr);
  $("<td></td>").text(user0.amount).appendTo($tr);
  $tr.appendTo("#user > tbody");


  // create additional rows for remaining user_data
  users.forEach(function(user) {
    total += user.amount;
    var $tr = $("<tr></tr>");
    $("<td></td>").text(user.time1).appendTo($tr);
    $("<td></td>").text(user.time2).appendTo($tr);
    $("<td></td>").text(user.amount).appendTo($tr);
    $tr.appendTo("#user > tbody");
  });

  // total was calculated above
  $tr = $("<tr></tr>");
  $("<td colspan=3>Total</td>").appendTo($tr);
  $("<td></td>").text(total).appendTo($tr);
  $tr.appendTo("#user > tbody");
});
table {
  border-collapse: collapse;
}

td {
  padding: 20px;
  border: 1px solid black;
  text-align: center;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table id="user">
  <thead>
    <tr>
      <th>User Name</th>
      <th>Time 1</th>
      <th>Time 2</th>
      <th>Amount</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

No need to use recursion for your case. Please take a look the below script and read the ment:

var data = [{
  "user_data": [{
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2550,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "hulk"
}, {
  "user_data": [ {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 1700,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }, {
    "amount": 2125,
    "time1": "2017/04/05",
    "time2": "2017/04/06"
  }],
  "name": "gomu"
}];

for (i=0; i<data.length; i++) {
  var rows = data[i].user_data.length;
  var html = '';
  var total = 0;
  
  // start rendering user_data
  for (r=0; r<rows; r++) {

    html += '<tr>';
    if (r == 0) { // render for first row of user data only
      html += '<td rowspan="'+rows+'">'+data[i].name+'</td>';
    }
    html += '<td>'+data[i].user_data[r].time1+'</td>';
    html += '<td>'+data[i].user_data[r].time2+'</td>';
    html += '<td>'+data[i].user_data[r].amount+'</td>';
    html += '</tr>';
    total += data[i].user_data[r].amount;
    
  }

  // render total row
  html += '<tr><td colspan="3">Total:</td><td>'+total+'</td></tr>';

  // append user_data into the table
  $('table#user tbody').append(html);
}
th, td {
  border: 1px solid;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="user">
    <thead>
        <tr>
          <th>User Name</th>
          <th>Time 1</th>
          <th>Time 2</th>
          <th>Amount</th>
        </tr>
    </thead>
    <tbody>
      
    </tbody>
</table>

You're missing the total calculation logic in your iteration. I added in some extra formatting for the rowspan and colspan in the total row:

data.forEach((obj) => {
    var userData = obj.user_data;
    var rowTotal = 0;
    var rowsize;
    tableStr += '<tr><td rowspan="'userData.length'">obj.name</td>
    userData.forEach((o, index) => {
        if(index > 0) {
            tableStr += '<tr>'
        } else {
            rowsize = Object.keys(o).length;
        }
        Object.values(o).forEach((value) => {
            tableStr += '<td>' + value + '</td>';
        });
        rowTotal += o.amount;
        tableStr += '</tr>';
    });
    tableStr += '<tr><td colspan="' + rowsize + '">Total</td><td>'+rowTotal+'</td></tr>'
});

Note: This snippet assumes the "user_data" object always has an "amount" value that accumulates for the total.

发布评论

评论列表(0)

  1. 暂无评论