Steve
Steve

Reputation: 14922

AngularJS expandable table with aligned columns

With every example I can find of an expandable table using ng-repeat, the expanded row is "separate" content, such as an independent table inside the detail row. I have done many expandable tables using these methods, something like

<tr ng-repeat-start="item in faceted.table.data" ng-init="item.showDetails = false" ng-click="faceted.table.showDetailRow($index)">
        <td>
            <a href="" class="table-row-toggle">
                <i class="nc-icon-mini lg fw arrows-2_small-right " ng-class="{'rotate-90': item.showDetails}"></i>
            </a>
        </td>
        <td>{{item.partner_name}}</td>
        <td>{{item.type}}</td>
        <td>>{{m.merchant_name}}</td>
    </tr>
    <tr class="table-details" ng-repeat-end="item in faceted.table.data" ng-if="faceted.table.detailsShown === $index">
        <td></td>
        <td colspan="7">
            <table class="table table-unstyled">
                <tbody>
                    <tr ng-repeat="m in item.merchants">
                        <td>{{m.merchant_name}}</td>
                        <td>{{m.type}}</td>
                        <td>{{m.state}}</td>
                        <td><img src="images/status.svg" alt="status"></td>
                        <td>{{m.modified_by}}</td>
                        <td>{{m.modified_date}}</td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>

However, what I need to have this time is the "detail" rows have to be part of the main table so the columns align, as in this Axure screenshot:

enter image description here

The gray rows are children of the white rows. I can access the data as in my code example, but cannot make the columns align.

I have tried a few ways, but nothing so far seems to work.

Upvotes: 2

Views: 2133

Answers (3)

Steve
Steve

Reputation: 14922

FWIW, I finally got this to work by starting with the answers from others and working it into this:

        <table class="table table-datatable table-hover table-border-bottom">
        <thead>
            <tr>
                <th>&nbsp;</th>
                <th>Partner</th>
                <th>Merchants</th>
                <th>Modified</th>
                <th>Status</th>
            </tr>
        </thead>

        <tbody>
            <tr ng-repeat-start="item in mob.dashboardTableData">
                <td>    
                    <i class="nc-icon-mini lg fw arrows-2_small-right " ng-class="{'rotate-90': item.showDetails}"></i>
                </td>
                <td class="text-nowrap">{{item.partner_name}}</td>
                <td><span ng-repeat="m in item.merchants">{{m.merchant_name}}<font ng-if="!$last">, </font></span></td>
                <td>{{item.modified_date}}<br>{{item.modified_by}}</td>
                <td>{{item.status}}</td>
            </tr>
            <tr class="table-details" ng-repeat-end ng-repeat="m in item.merchants">
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>{{m.merchant_name}}</td>
                <td>{{m.modified_date}}<br>{{m.modified_by}}</td>
                <td>{{m.status}}</td>
            </tr>
        </tbody>
    </table>

where the data is structured like so:

  {
"id": 1,
"partner_name": "Gap Industries",
"type": "Partner",
"state": "New",
"status": 2,
"modified_by": "John Smith",
"modified_date": "2016-04-10 12:37PM",
"merchants": [
  {
    "id": 1,
    "merchant_name": "Gap",
    "type": "Merchant",
    "state": "New",
    "status": 2,
    "modified_by": "John Smith",
    "modified_date": "2016-04-10 12:37PM"
  },
  {
    "id": 2,
    "merchant_name": "American Eagle Outfitters",
    "type": "Merchant",
    "state": "New",
    "status": 2,
    "modified_by": "John Smith",
    "modified_date": "2016-04-10 12:37PM"
  },
  {
    "id": 3,
    "merchant_name": "Old Navy",
    "type": "Merchant",
    "state": "New",
    "status": 2,
    "modified_by": "John Smith",
    "modified_date": "2016-04-10 12:37PM"
  }
]

},...

Upvotes: 0

kicken
kicken

Reputation: 2167

You can use <tbody> tags to create the sections in the table, one for the parent row and one to contain all the child rows. Just make sure the number of columns match between the parent and child sections.

<tbody ng-repeat-start="item in faceted.table.data" ng-init="item.showDetails = false">
    <tr ng-click="faceted.table.showDetailRow($index)">
        <td>
            <a href="" class="table-row-toggle">
                <i class="nc-icon-mini lg fw arrows-2_small-right " ng-class="{'rotate-90': item.showDetails}"></i>
            </a>
        </td>
        <td>{{item.partner_name}}</td>
        <td>{{item.type}}</td>
        <td colspan="4">{{m.merchant_name}}</td>
    </tr>
</tbody>
<tbody ng-repeat-end="item in faceted.table.data" ng-if="faceted.table.detailsShown === $index">
    <tr ng-repeat="m in item.merchants">
        <td></td>
        <td>{{m.merchant_name}}</td>
        <td>{{m.type}}</td>
        <td>{{m.state}}</td>
        <td><img src="images/status.svg" alt="status"></td>
        <td>{{m.modified_by}}</td>
        <td>{{m.modified_date}}</td>
    </tr>
</tbody>

Upvotes: 0

Larry Turtis
Larry Turtis

Reputation: 1916

You can achieve this using ng-repeat-start and ng-repeat-end. The key difference is that your detail objects need to be children of the parent objects, not children of the same object.

<tbody>
  <tr ng-repeat-start="parent in vm.parents">
  <tr class="parent-entry">
    <!-- cells go here ex:{{parent.data}} -->
  </tr>
  <tr class="child-entry" ng-repeat-end ng-if="parent.show">
    <!-- cells go here, ex:{{parent.child.data}}-->
  </tr>
  </tr>
</tbody>

Upvotes: 1

Related Questions