JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://raw.github.com/bruth/groupby/master/groupby.js"></script>
SCSS
.group {
margin-bottom: 10px;
> * {
display: inline-block;
vertical-align: middle;
}
.group-label {
padding: 5px 10px;
font-size: 18px;
font-weight: bold;
.group-key {
margin-right: 5px;
}
}
.group-table {
border-collapse: collapse;
}
.group-table td, .group-table th {
border: 1px solid #ddd;
padding: 5px;
}
.group-table th {
background-color: #eee;
}
}
JavaScript
var keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
// Generate a list of objects with random properties
function randomObjects(size) {
var array = [];
for (var i=0; i < size; i++) {
var obj = {};
_.each(keys, function(key) {
obj[key] = Math.floor(Math.random() * 10);
});
array.push(obj);
}
return array;
}
function groupByHtml(groups, keys, sep) {
var html = [],
sep = sep || ',';
// Build group
_.each(groups, function(list, groupKey) {
var group = $('<div>').addClass('group'),
label = $('<span>').addClass('group-label'),
table = $('<table>').addClass('group-table'),
header = $('<tr>'),
tbody = $('<tbody>');
if (_.isString(groupKey)) {
_.each(groupKey.split(sep), function(tok) {
label.append('<span class=group-key>' + $.trim(tok) + '</span>');
});
} else {
label.append('<span class=group-key>' + groupKey + '</span>');
}
// Build table
_.each(list, function(obj, i) {
var tr = $('<tr>');
_.each(obj, function(value, key) {
// Add group label on first iteration
if (keys.indexOf(key) >= 0) {
if (i == 0) {
}
} else {
// Add head row on first iteration
if (i == 0) {
header.append('<th>' + key + '</th>');
}
tr.append('<td>' + value + '</td>');
}
});
tbody.append(tr);
});
$('<thead>').appendTo(table).append(header);
table.append(tbody);
group.append(label, table);
html.push(group);
});
return html;
}
function log() {
$('body').append.apply($('body'), groupByHtml.apply(this,...