Stock Data Table

by michiganfootball20

HTML

<table class="table analyzer-table">
    <thead>
        <tr class="agg-cols">
            <th rowspan="2">Group Name</th>
            <td class="column-group" colspan="3">Total</td>
            <td class="column-group" colspan="3">Q4 2014 (Current)</td>
            <td class="column-group" colspan="3">Q3 2014</td>
        </tr>
        <tr class="stat-cols">
            <th>#</th>
            <th>Return</th>
            <th>STD</th>
            <th>#</th>
            <th>Return</th>
            <th>STD</th>
            <th>#</th>
            <th>Return</th>
            <th>STD</th>
        </tr>
    </thead>
    <tbody>
        <tr data-cat-name="grand-total" data-group-level="1" data-group-collapse="collapse" class="agg-row level-1">
            <td class="cat-name"><div class="cat-name-inner"><span class="glyphicon glyphicon-chevron-right"></span><span class="text">Grand Total</span></div></td>
            <td class="stat-val int">170</td>
            <td class="stat-val percent"><span class="green-number">1.72%</span></td>
            <td class="stat-val float">2.017</td>
            <td class="stat-val int">98</td>
            <td class="stat-val percent">1.32%</td>
            <td class="stat-val float">3.017</td>
            <td class="stat-val int">72</td>
            <td class="stat-val percent">1.92%</td>
            <td class="stat-val float">1.017</td>
        </tr>
        <tr data-cat-name="software" data-cat-parent="grand-total" data-group-level="2" data-group-collapse="collapse" class="agg-row level-2 hide">
            <td class="cat-name"><div class="cat-name-inner"><span class="glyphicon glyphicon-chevron-right"></span><span class="text">Software</span></div></td>
            <td class="stat-val int">170</td>
            <td class="stat-val percent"><span class="red-number">1.72%</span></td>
            <td class="stat-val float">2.017</td>
            <td class="stat-val int">98</td>
            <td class="stat-val percent">1.32%</td>
        ...

CSS

/* Borders and fonts */
.analyzer-table td, .analyzer-table th { border: 1px solid #c6d5e1;}
.analyzer-table {border-top: #cdcdcd 1px solid;}
.analyzer-table th {font-weight: normal;}
span.green-number {color: #1b7b00;}
span.red-number {color: #B90101;}

/* Basic table spacing and alignment */
.analyzer-table thead>tr>td,
.analyzer-table thead>tr>th,
.analyzer-table tbody>tr>th,
.analyzer-table tbody>tr>td {vertical-align: middle; text-align: center;}
.analyzer-table td.cat-name {cursor: pointer;}
.analyzer-table td.cat-name span.text {padding-left: 8px;}
.analyzer-table tr.agg-row td.cat-name {text-align: left;}
.analyzer-table tr.stock-row td.cat-name {text-align: right;}
.analyzer-table tr.stock-row td.cat-name .cat-name-inner {padding-right: 10px;}
.analyzer-table tr.level-1 td.cat-name .cat-name-inner {padding-left: 0px;}
.analyzer-table tr.level-2 td.cat-name .cat-name-inner {padding-left: 10px;}

/* Basic table background colors */
.analyzer-table tbody tr.stock-row:nth-child(even) {background: #F6F8FA;}
.analyzer-table tbody tr.stock-row:nth-child(odd) {background: #F9FBFC;}
.analyzer-table tbody tr.agg-row td.cat-name, 
.analyzer-table thead tr.agg-cols td.column-group,
.analyzer-table thead tr.stat-cols th {color: #cfdce7;}
.analyzer-table tbody tr.agg-row.level-1 td.cat-name,
.analyzer-table thead tr.agg-cols td.column-group {background: #4b708d;}
.analyzer-table tbody tr.agg-row.level-1 td.stat-val {background: #EDF1F4;}
.analyzer-table tbody tr.agg-row.level-2 td.cat-name, 
.analyzer-table thead tr.stat-cols th {background: #6F8DA4;}
.analyzer-table tbody tr.agg-row.level-2 td.stat-val {background: #F1F4F6;}

/* Table hover affects */
.analyzer-table tbody tr.agg-row:hover td.cat-name,
.analyzer-table thead tr.agg-cols td.column-group:hover,
.analyzer-table thead tr.stat-cols th:hover {color: #fff;}
.analyzer-table tbody tr:hover td.stat-val {opacity: .8;}

JavaScript

$(document).ready(function () {

    function toggleCat(aggRow, expand) {
        if(expand) {
            $(aggRow).attr('data-group-collapse','expand'); //Switch the collapse attribute
            $(aggRow).find('td.cat-name span.glyphicon').removeClass('glyphicon-chevron-right').addClass('glyphicon-chevron-down'); //Toggle between chevron-right and chevron-down
        }
        else {
            $(aggRow).attr('data-group-collapse','collapse'); //Switch the collapse attribute
            $(aggRow).find('td.cat-name span.glyphicon').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-right'); //Toggle between chevron-right and chevron-down
        }
        
        var level = parseInt($(aggRow).attr('data-group-level'),10); //Get current group level
        var catName = $(aggRow).attr('data-cat-name'); //Get current cat name
        //Build array of direct children
        var child = $(aggRow).next();
        while (level < $(child).attr('data-group-level')) { //Loop until next same level group is reached
            if (expand) { //If expanding, show direct children rows
                if ($(child).attr('data-group-level') == level + 1) $(child).removeClass('hide');
            }
            else { //If contracting, contract all children down the ladder
                $(child).addClass('hide');
                toggleCat(child,false);
            }
            child = $(child).next();
        }
    }

    $('table.analyzer-table tr.agg-row td.cat-name').on('click', function () {
        var row = $(this).closest('tr');
        if($(row).attr('data-group-collapse') == 'collapse') toggleCat(row,true);
        else toggleCat(row,false);
    });
});