-1

I have an html table, <tbody> of it is generated with angular ng-repeat. Here is my html:

<tbody>
    <tr ng-repeat-start="car in carList | filter:tableFilter" ng-click="activeRow = car.name">
        <td><a target="_blank" href="{{car.carLink}}">{{car.name}}</a></td>
        <td>{{car.review}}</td>
        <td>{{car.rating}}</td>
        <td>{{car.fiveStarPercent}}</td>
        <td>{{car.recommended}}</td>
        <td>{{car.price}}</td>
    </tr>
    <tr ng-repeat-end ng-show="activeRow==car.name">
        <td>{{car.name}}</td>
    </tr>
</tbody>

I need to do so when you click on the row, new row is showing up, but when you click on another row I need the first one to hide.

Here is table in browser with an active row:

enter image description here

I have tried to do this with ng-show like this:

ng-show="activeRow==car.name"

activeRow is a $scope variable inside of my controller. The problem is, that new row is showing up, but not hiding when you click on another.

How can I fix that?

Michael
  • 15,386
  • 36
  • 94
  • 143
  • Try to encapsulate the `activeRow` property inside an object, like `$scope.model = { activeRow: 'someValue' };` and then on the HTML `ng-show="model.activeRow==car.name"`. – bmleite Sep 12 '14 at 16:57

2 Answers2

4

You need to provide a namespace for your activeRow variable because ng-repeat has its own scope.

<div ng-app="app" ng-controller="mainCtrl as main">
  <table class="table table-striped table-bordered">
    <tbody>
        <tr ng-repeat-start="car in carList | filter:tableFilter" ng-click="main.activeRow = car.name">
            <td><a target="_blank" href="{{car.carLink}}">{{car.name}}</a></td>
            <td>{{car.review}}</td>
            <td>{{car.rating}}</td>
            <td>{{car.fiveStarPercent}}</td>
            <td>{{car.recommended}}</td>
            <td>{{car.price}}</td>
        </tr>
        <tr ng-repeat-end ng-show="main.activeRow==car.name">
            <td colspan="6">{{car.name}}</td>
        </tr>
    </tbody>
  </table>
</div>

Working demo using the "controller as" technique: http://codepen.io/Chevex/pen/KAmFB

This technique is functionally identical to doing this in your controller:

app.controller('mainCtrl', function ($scope) {
    $scope.main = this;
    this.activeRow = "Lightning McQueen";
});

Angular allows the "as" syntax in ng-controller definitions as a simple shortcut for creating a namespace on your scope that refers to the controller function's execution context (this). It's a nice way to create a namespace without having to create a random meaningless object such as $scope.model = { ... };.

CatDadCode
  • 58,507
  • 61
  • 212
  • 318
1

Since the ng-repeat directive creates a new scope and the activeRow property is on the parent's controller scope, you will have to encapsulate that property inside an object. This way scope's prototypal inheritance will work as expected.

On the controller:

$scope.model = { activeRow: 'someValue' };

And on the HTML:

ng-show="model.activeRow == car.name"

More info on prototypal inheritance here.

Community
  • 1
  • 1
bmleite
  • 26,850
  • 4
  • 71
  • 46