Question

OK, so I want to create a dynamic nested hierarchy of tables. I get they data no problem, but using ng-repeat at each level causes the parent table to insert child data for a specific row into each row of the parent table. I want to prevent this, I have tried using ng-repeat-start and ng-repeat-end, however, because of the table nesting I cannot add the end tag in an appropriate place to stop the repeat.

UPDATE Let me clarify a bit here, I have 3 nested tables, the top level table has list of groups, the first child table is a list of all of the items that belong to a specific group in the parent table. When the user clicks the expand button, I populate the child table based on which row in the parent table was clicked, this is OK, however the child table now shows up in each of the parent table rows instead of just the row that was clicked.

Plunker Link http://plnkr.co/edit/RVOnf9wBF3TzXauzvMfF

HTML:

<table id="sicGroupTable" class="RadGrid_Metro">
   <thead>
       <tr>
          <td>Sic Code Group</td>
       </tr>
   </thead>
       <tbody ng-repeat="group in sicCodeGroup">
           <tr class="rgRow">
               <td class="rgExpandCol"><img class="rgExpand" ng-click="expandRow(group.GroupId)" ng-model="hideTwoDigitSub" /></td>
               <td><input type="checkbox" ng-model="SelectGroup" /></td>
               <td>{{group.GroupName}}</td>
           </tr>
           <tr ng-hide="hideTwoDigitSub">
               <td></td>
               <td>
                   <table id="sic2DigitTable" class="RadGrid_Metro">
                       <thead>
                           <tr>
                               <th>2 digit sic Code</th>
                           </tr>
                       </thead>
                           <tbody>
                               <tr ng-repeat="twoDigitSic in twoDigitSicCodes" class="rgRow">
                                   <td class="rgExpandCol"><img class="rgExpand" ng-click="expandRow(twoDigitSic.SicCode)" /></td>
                                   <td><input type="checkbox" ng-model="Select2DigitSicCode" /></td>
                                   <td>{{twoDigitSic.SICCode2}} - {{twoDigitSic.Title}}</td>
                                </tr>
                                <tr>
                                <td></td>
                                 <td>
                                     <table id="sic4DigitTable" class="RadGrid_Metro">
                                         <thead>
                                             <tr>
                                                 <th>4 digit sic code</th>
                                             </tr>
                                         </thead>
                                             <tbody>
                                                 <tr class="rgRow">
                                                     <td class="rgExpandCol"><img class="rgExpand" ng-click="expandRow(sicCode.SicCode)" /></td>
                                                     <td><input type="checkbox" ng-model="Select2DigitSicCode" /></td>
                                                     <td>{{sicCode.SicCode}} - {{sicCode.Title}}</td>
                                                 </tr>
                                                 <tr>
                                                     <td></td>
                                                 </tr>
                                              </tbody>
                                          </table>
                                      </td>
                                  </tr>
                              </tbody>
                          </table>
                      </td>
                  </tr>
              </tbody>
          </table>

JavaScript:

var app = angular.module("apptSetting", ['ngResource'])

app.factory('dataFactory',
    function ($resource) {
        return {
            getSicGroups: $resource('../Packages/GetJsonSicCodeGroups'),
            expandRow: $resource('../Packages/GetExpandedRowData')
        }
    });

app.controller('aPackageController', ['$scope', 'dataFactory', function ($scope,  dataFactory) {
function init() {
    $scope.hideTwoDigitSub = true;
    $scope.hideFourdigitsub = true;
}
$scope.sicCodeGroup = dataFactory.getSicGroups.query({}, isArray = true);
$scope.twoDigitSicCodes = null;
$scope.expandRow = function (groupId, sicCode) {
    if (groupId != undefined)
    {
        $scope.twoDigitSicCodes = dataFactory.expandRow.query({ GroupId: groupId }, isArray = true);
        $scope.hideTwoDigitSub = false;
        if (sicCode != null && sicCode != undefined && sicCode != "") {
            if (sicCode.length == 2) {
                $scope.hideTwoDigitSub = false;
                $scope.twoDigitSicCodes = dataFactory.Get2DigitSicCodes.query({ GroupId: groupId }, isArray = true);
            }
        }
    }     
}
    init();
}])
Was it helpful?

Solution

The issue is that you're using a single boolean hideTwoDigitSub to control all the trs created by your ngRepeat:

<tr ng-hide="hideTwoDigitSub">

So when you set $scope.hideTwoDigitSub = false; every ngHide within your ngRepeat gets that false and thus all the tr elements are shown.

Radio Button Fix

Instead of using a boolean I'd set hideTwoDigitSub to the groupId for the row you want to show (and maybe rename hideTwoDigitSub to showTwoDigitSub since the variable now indicates which row to show).

So inside your expandRow() function I'd set which row to show by changing:

$scope.hideTwoDigitSub = false;

to

$scope.hideTwoDigitSub = groupId;

And change the above tr to:

<tr ng-hide="hideTwoDigitSub != group.GroupId">

So the row will be hidden unless your control variable hideTwoDigitSub is not equal to the current groups GroupId.

Or it might be clearer to use ngShow (note I changed the hideTwoDigitSub to showTwoDigitSub in this example since it's clearer):

<tr ng-show="showTwoDigitSub == group.GroupId">

radio button plunker

Checkbox solution

This approach is easiest done switching hideTwoDigitSub to showTwoDigitSub- so everything below assumes that.

For this approach, inside init() I'd set your control variable to be an array:

$scope.showTwoDigitSub=[];

And then toggle the appropriate control inside expand:

$scope.showTwoDigitSub[groupId] = !$scope.showTwoDigitSub[groupId]; 

And use the array inside your html:

<tr ng-show="showTwoDigitSub[group.GroupId]">

checkbox plunker

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top