Search code examples
javascriptangularjsangularjs-ng-repeat

Using Ng-repeat in table, alternatives to multiple tbody?


I have multiple objects, and for each object I am trying to generate multiple rows. Please see the code snippet:

<table style="width:100%">
  <thead>
    <tr>
      <th colspan="3" style="background:whitesmoke; font-size:17px; font-weight: 500">
        Release Criteria <span ng-if="$ctrl.casesModalState.IsEditingCase"> <button ng-click="$ctrl.openCriteriaModal()" type="button" style="float:right; border:none; color: mediumblue; background-color:transparent; margin-right:15px; font-weight:500; font-size: 14px !important"><i class="fa fa-plus" style="margin-right:5px"></i>Add Criteria</button></span>
      </th>
    </tr>
  </thead>

  <tbody ng-repeat="caseObj in $ctrl.businessCaseService.selectedCase.listOfActiveBusinessCriteria track by $index">
    <tr>
      <td class="criteriaHeader">{{caseObj.criteriaHeader}}</td>
      <td class="valueHeader">{{caseObj.criteriaValueHeader}}</td>
    </tr>
    <tr ng-repeat="criteriaObj in caseObj.criteriaOptions track by $index">
      <td class="valueLabel">{{criteriaObj.criteriaLabel}}</td>
      <td class="valueClass" ng-attr-id="{{'listIndexValue-' + $index}}" contenteditable="false">{{criteriaObj.value}}</td>
    </tr>
  </tbody>
</table>

This actually does what I want it to, but it isn't good to have multiple tbody. I can't use a div here to put my ng-repeat in, so I'm not sure what other options I have. Attached an image of the rendered table. This is exactly what I want, but without the multiple tbody.

enter image description here


Solution

  • You can use ng-repeat-start with ng-repeat-end to make the two tr be treated as one by the ng-repeat:

    function myCtrl($scope) {
      $scope.objects = [{
          type: "MoU",
          children: [{
            label: "yes",
            value: 0
          }, {
            label: "no",
            value: 0
          }],
        },
        {
          type: "Incentive",
          children: [{
            label: "yes",
            value: 1
          }, {
            label: "no",
            value: 1
          }],
        },
        {
          type: "Impact",
          children: [{
            label: "yes",
            value: 1
          }, {
            label: "no",
            value: 1
          }],
        }
      ];
    }
    
    const app = angular.module("app", [])
      .controller("myCtrl", myCtrl);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
    
    <table style="width:100%" ng-app="app" ng-controller="myCtrl as $ctrl">
      <thead>
        <tr>
          <th colspan="3">
            Release Criteria
          </th>
        </tr>
      </thead>
    
      <tbody>
        <tr ng-repeat-start="caseObj in objects">
          <td class="criteriaHeader">{{caseObj.type}}</td>
          <td class="valueHeader">{{caseObj.children.length}}</td>
        </tr>
        <tr ng-repeat-end ng-repeat="child in caseObj.children track by $index">
          <td>{{child.label}}</td>
          <td ng-attr-id="{{'listIndexValue-' + $index}}">{{child.value}}</td>
        </tr>
      </tbody>
    </table>