Async Expanding Rows.

This doesn't use an addon because it would need to store based on index. And need to know when to reset the data because if it set on the datagrid data change we would always loose our expanded rows. So it keeps a cache in the controller to manage the collapsed rows that are now showing. Then it can expand and collapse async if needed.

by Wes Jones

HTML

<script src="https://rawgithub.com/webux/ux-angularjs-datagrid/master/build/latest/angular-ux-datagrid.js"></script>
<div ng-controller="simpleArray" class="layout">
    <div class="datagridHeader group">
        <div class="col col1">Path</div>
        <div class="col col2">ID</div>
        <div class="col col4">CT</div>
        <div class="col col3">Height</div>
        <div class="col col5">Input</div>
    </div>
    <div ux-datagrid="items" class="datagrid" data-grouped="'children'" addons="overrides">
        <script type="template/html" data-template-name="group" data-template-item="item">
            <div class="group {{fake}}" ng-click="myToggle(item)">
                <div class="col col1">{{item.id}}</div>
                <div class="col col2">{{$id}}</div>
                <div class="col col4">{{counter}}</div>
                <div class="col col3">height 20px</div>
                <div class="col col5"></div>
            </div>
        </script>
        <script type="template/html" data-template-name="default" data-template-item="item">
            <div class="row {{fake}}">
                <div class="col col1">{{item.id}}</div>
                <div class="col col2">{{$id}}</div>
                <div class="col col4">{{counter}}</div>
                <div class="col col3">height 40px</div>
                <div class="col col5"><input type="text"></div>
             </div>
         </script>
         <script type="template/html" data-template-name="sub" data-template-item="item">
             <div class="sub {{fake}}">
                 <div class="col col1">{{item.id}}</div>
                 <div class="col col2">{{$id}}</div>
                 <div class="col col4">{{counter}}</div>
                 <div class="col col3">height 30px</div>
                 <div class="col col5"><input type="text"></div>
              </div>
          </script>
     </div>
 </div>

CSS

html, body {
    margin: 0px;
    padding: 0px;
    width: 100%;
    height: 100%;
}
/**************** LAYOUT ****************************/
.layout {
    position: absolute;
    top: 20px;
    left: 20px;
    right: 20px;
    bottom: 20px;
    margin: auto;
    border: 1px solid #336699;
}

/**************** Datagrid Header *******************/
.datagridHeader {
    width: 100%;
    height: 20px;
}

/**************** Standard Datagrid CSS *************/
.datagrid {
    position: absolute;
    top: 20px;
    left: 0px;
    right: 0px;
    bottom: 0px;
}
.row {
    height: 16px;
    background-color: #FFFFFF;
    border-bottom: 1px solid #000000;
}

/****************** Row Colors and Heights **********/
.group {
    background-color:#333333;
    height: 20px;
    font-size: 12px;
    font-weight: bold;
    color: #FFFFFF;
    line-height: 20px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

.overlay {
    position: absolute;
    top: 0px;
    left: 0px;
    background-color: #FFFFFF;
    width: 100%;
    height: 100%;
}

.row {
    background-color:#efefef;
    height: 40px;
    line-height: 40px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}
.row:nth-child(odd) {
    background-color:#dfdfdf;
}

.row > div {
    /*display: inline-block;*/
}

.sub {
    background-color:#99CCFF;
    height: 30px;
    line-height: 30px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}
.sub:nth-child(odd) {
    background-color:#AADDFF;
}

.sub > div {
    /*display: inline-block;*/
}

/****************** CSS FOR FADING IN ROWS AND CHUNKS and hiding them when they are not yet compiled **********/
.datagrid-row > * {
    -webkit-transition: opacity 0.5s ease-out;
    -moz-transition: opacity 0.5s ease-out;
    -ms-transition: opacity 0.5s ease-out;
    -o-transition: opacity 0.5s ease-out;
    transition: opacity 0.5s ease-out;
}

.uncompiled > * {
    visibility: hidden;
    opacity:...

JavaScript

// create a list of groups with an id, name, and type
function createGroupedList(len) {
    var i = 0, group, rand, items = [];
    while (i < len) {
        rand = Math.random();
        rand = rand >= 0.8 ? rand : 0;
        if (!group || Math.round(rand)) {
            items.push(group = {
                id: (items.length + 1) + '',
                name: 'Group ' + (items.length + 1),
                type: 'group',
                children: []
            });
        }
        i += 1;
    }
    return items;
}

// create a random number of rows
function createRows(group) {
    var i = 0, len = Math.floor(Math.random() * 5) + 1, children = [];
    while (i < len) {
        children.push({id: group.id + '.' + i, children: []});
        i += 1;
    }
    return children;
}

// our controller
window.simpleArray = function ($scope) {
    var cache = {};
    $scope.items = createGroupedList(200);
    $scope.myToggle = function (group) {
        //setTimeout(function () {// async is optional
        // keep a cache object that stores each sub array so we can just put it back.
            cache[group.id] = cache[group.id] || createRows(group);
            group.children = group.children.length ? [] : cache[group.id];
            $scope.$broadcast(ux.datagrid.events.UPDATE);
        //}, 1);// if using the async.
    }
};

// add an override so we can determine what object gets what template.
angular.module('ux').factory('overrides', function () {
    // the datagrid instance is passed to every addon
    return function (inst) {
        // override the default dg.templateModel.getTemplate which looks for an _template property
        // on each item to determine it's template. Replace it with ours that will make odd numbers
        // have the alternate template.
        inst.templateModel.getTemplate = function (item) {
            var name = 'default';
            if (item.type === 'group') {
                name = 'group';
            } else if (item.id % 2) {
    ...