3
votes

I have a plunker.

I'm using angular-ui-grid with 2 levels of expandable rows.

  1. People - expandable
  2. Friends - expandable
  3. Pets - regular

The People level has this expandableRowTemplate

<div ui-grid="row.entity.subGridOptions" ui-grid-expandable  style="height:150px;"></div>

and these options:

$scope.gridOptions = {
  expandableRowTemplate: 'expandableRowTemplate.html',
  expandableRowHeight: 150
}

The Friends level has this expandableRowTemplate:

<div ui-grid="row.entity.subGridOptions" style="height:150px;"></div>

and these options:

data[i].subGridOptions = {
      columnDefs: [ {name:"Id", field:"id"},{name:"Name", field:"name"} ],
      data: friends,
      expandableRowTemplate: 'expandableRowTemplate2.html',
      rowTemplate: 'rowTemplate.html'
    }

The Pets level has options like this:

friends[j].subGridOptions = {
      columnDefs: [ {name:"Name", field:"name"} ],
      data: friends[j].pets
    }

On the Friends level, I want to be able to show a groupname with merged cells and a single piece of text. Kind of like a header, but inside the list. The list will be sorted beforehand, so I can just insert a number of groupnames where I want them. This is done by adding a custom rowtemplate (see above) to this level and testing the id of the row like this (in reality I will test a property):

<div>
  <div ng-if="row.entity.id !== 0">
    <div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"  ui-grid-cell></div>
  </div>

  <div ng-if="row.entity.id === 0" >
    <div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name"
         class="ui-grid-cell" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"
         >
    </div>

     <div class="ui-grid-cell-contents">
        <div>
          {{row.entity.name}}
        </div>
      </div>

  </div>
</div>

This way works fine in other examples when not using expandable rows.

When using expandable rows, it seems like the row where I want to show the groupname is rendered twice, once correctly, and once in the rowheader cell (See Rosanne Barret in picture below)

row is rendered twice

how can i prevent this? I only want the text to be shown once

1
Do you want to include the first entry ('Rosanne' ) also in the Friends List and then have a custom header or omit the first entry?karthick
omit the first entrystombeur
I have added a solution with a header and listing all the entries in the friends list. See if it helps. Why do you want to omit the first entry? Dont you need to show all the friends list as expandable grid?karthick
sorry, I misunderstood! you're right, I thought you meant the left/body thingy. Omitting the first entry was just a hack for the example. Thanks for all your help!stombeur

1 Answers

2
votes

After some debugging and digging in the src. I found the reason is expandable grid. The gird creates two containers one for expandable icon and another for the content. So when we apply data the content is duplicated in the container that has the expandable button and the container that have the text.

The only way to solve is to use the merge row functionality and check the property of the container that holds these cells, which can be accessed by colContainer in the scope.

expandable button cell has a colContainer name as 'left' and the content has the colContainer name as 'body'.

What I did for merge row is add the merge true and sample title to the data set

var friends = data[i].friends;
friends.unshift({
  merge: true,
  title: 'Test',
  bodyTitle: 'Body Title'
});

Next is to modify the rowtemplate.html

<div>
   <div ng-if="row.entity.merge && colContainer.name == 'left'">{{row.entity.title}}</div>
   <div ng-if="!row.entity.merge" ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"  ui-grid-cell></div>
</div>

or

<div>
   <div ng-if="row.entity.merge && colContainer.name == 'body'">{{row.entity.title}}</div>
   <div ng-if="!row.entity.merge" ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"  ui-grid-cell></div>
</div>

Choose either one depending on where you want to show the header. I prefer the 'body', due to width restrictions placed on the expandable button cell.

Plunkr example http://plnkr.co/edit/wGhvtVGwouO01thkx9Z6?p=preview

Note: Plunkr example has both 'left' and 'body' in the row template. So that you can see the difference.