Expandable Table Rows

by bizamajig

HTML

<script src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"></script>
<script src="http://yui.yahooapis.com/combo?3.5.1/build/datatable-message/assets/skins/sam/datatable-message.css&amp;3.5.1/build/datatable-sort/assets/skins/sam/datatable-sort.css&amp;gallery-2012.05.16-20-37/build/gallery-datatable-row-expansion/assets/skins/sam/gallery-data"></script>
<link rel="stylesheet" href="http://yui.yahooapis.com/combo?3.5.1/build/cssfonts/fonts-min.css&amp;3.5.1/build/cssreset/reset-min.css&amp;3.5.1/build/cssgrids/grids-min.css">
<div class="yui3-skin-sam">
    <div id="my-table"></div>
</div>

CSS

.yui3-datatable-message {
    display: none;
}
.yui3-datatable-message-visible .yui3-datatable-message {
    display: table-row-group;
}
.yui3-skin-sam .yui3-datatable-message-content {
    -moz-border-bottom-colors: none;
    -moz-border-image: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    border-bottom-color: #CBCBCB;
    border-bottom-style: solid;
    border-bottom-width: 1px;
    border-left-color-ltr-source: physical;
    border-left-color-rtl-source: physical;
    border-left-color-value: -moz-use-text-color;
    border-left-style-ltr-source: physical;
    border-left-style-rtl-source: physical;
    border-left-style-value: none;
    border-left-width-ltr-source: physical;
    border-left-width-rtl-source: physical;
    border-left-width-value: 0;
    border-right-color-ltr-source: physical;
    border-right-color-rtl-source: physical;
    border-right-color-value: -moz-use-text-color;
    border-right-style-ltr-source: physical;
    border-right-style-rtl-source: physical;
    border-right-style-value: none;
    border-right-width-ltr-source: physical;
    border-right-width-rtl-source: physical;
    border-right-width-value: 0;
    border-top-color: -moz-use-text-color;
    border-top-style: none;
    border-top-width: 0;
    padding-bottom: 4px;
    padding-left: 10px;
    padding-right: 10px;
    padding-top: 4px;
}
#yui3-css-stamp.skin-sam-datatable-message {
    display: none;
}
.yui3-datatable-sortable-column {
    z-index: 1;
}
.yui3-datatable-sortable-column:focus, .yui3-datatable-sortable-column:active {
    z-index: 2;
}
.yui3-skin-sam .yui3-datatable-sortable-column {
    cursor: pointer;
}
.yui3-skin-sam .yui3-datatable-columns .yui3-datatable-sorted, .yui3-skin-sam .yui3-datatable-sortable-column:hover {
    background-color: #F1F2F3;
}
.yui3-skin-sam .yui3-datatable-sort-liner {
    display: block;
    height: 100%;
    padding-right: 15px;
    position:...

JavaScript

YUI.add("cacheable-datatable-row-expansion", function (a) {
    function b(j) {
        b.superclass.constructor.call(this, j);
    }
    b.NAME = "DataTableRowExpansionPlugin";
    b.NS = "rowexpander";
    b.ATTRS = {
        uniqueIdKey: {
            value: "",
            validator: a.Lang.isString
        },
        remoteURL: {
            value: "",
            validator: a.Lang.isString
        },
        remoteQuery: {
            value: "",
            validator: a.Lang.isString
        }
    };
    b.column_key = "row-expander";
    b.row_class = "row-expansion";

    b.cache_key = 'datatable-row-expansion-cache';           

    b.cache = a.Node.create('<div id="' + b.cache_key + '"></div>');
    
    function g(k) {
        var n = this.rowexpander;
        var j = k.data[n.get("uniqueIdKey")];
        var m = n.open_rows[j];
        k.td.addClass("row-toggle");
        k.td.replaceClass("row-(open|closed)", m ? "row-open" : "row-closed");
                        
        k.td.on("click", function () {
            n.open_rows[j] = !n.open_rows[j];
            a.later(0, this, function () {
                this.syncUI();
            });
        }, this);
        
        k.cell.set("innerHTML", '<a class="row-expand-nub" href="javascript:void(0);"></a>');
        if (m) {
            var r = "";
            for (var l = 0; l <= n.col_count.pre; l++) {
                r += '<td class="yui3-datatable-cell pre-row-expansion">&nbsp;</td>';
            }

            var t = k.cell.ancestor();            
            var tempDivID = b.cache_key + '-' + j;

            if(a.Lang.isObject(b.cache.one('> #' + tempDivID))){
                console.log('Found Existing Cache Row!');
            } else {
                b.cache.append('<div id="' + tempDivID + '"></div>');
                console.log('Adding New Cache Row!');
                
                //comment out remote load for fiddling 
                /*b.cache.one('> #' +...