2

I have a toggle button in a table row, once clicked, I'd like to leave the last clicked row visible, while hiding all other rows of the table.

This is done using two flags: 'showAll' (global) and 'showGridRow'- per row.

A row is displayed if one of the flags is true: ng-show="{{showAll}}||product.showGridRow"

code:

$scope.showAll = showAll;

$scope.toggleReadings = function toggleReadings(product) {
  if (product.showGridRow == undefined) {
    //if undefined, this is first click - set to false so it will be enabled immediatelly
    product.showGridRow = false;
  }

  product.showGridRow = !product.showGridRow;
  //if true, hide all others, else show all
  showAll = !product.showGridRow;

};
<table class="table table-striped">
  <thead>
    <tr>
      <th>Product ID</th>
      <th>Product Name</th>
      <th>Topic</th>
      <th>Active</th>
      <th>Readings</th>
    </tr>
  </thead>
  <tbody>                      
    <tr ng-repeat="product in products" ng-show="{{showAll}}||product.showGridRow">
      <td>{{product.productId}}</td>
      <td>{{product.productName}}</td>
      <td>{{product.topic}}</td>
      <td>{{product.Active}}</td>
      <td>
        <input type="button" value="..." ng-click="toggleReadings(product)" >
      </td>
    </tr>
  </tbody>
</table>

My Question:

This works only when placing a breakpoint at the beginning of the toggleReadings() function and debugging the code. While running the code "normally" nothing happens. What am I missing? Thanks!

4
  • 1
    This looks like a great time to use the built-in filter filter. Commented Jan 26, 2016 at 16:11
  • this isn't going to work as you expect. ng-repeat creates a child scope for each row, causing scope inheritance issues with the $scope.showAll primitive. the toggleReadings(product) function will, in effect, create a new $scope.showAll property for each row the first time the button is clicked, and will not affect the parent property, nor any of the properties created so far within each row other than itself. Commented Jan 26, 2016 at 16:12
  • this could be fixed by using an object instead of a primitive, but as @ryanyuyu mentioned, a filter makes more sense here than ng-show anyway. Commented Jan 26, 2016 at 16:14
  • I don't think a filter fits here conceptually, as whether the element is shown depends on the state of other elements/the state of the parent scope. I'm sure you could get a filter to work, but this seems like a perfectly fine use-case for ng-show. Commented Jan 26, 2016 at 16:32

2 Answers 2

1

Try this: https://jsfiddle.net/o5aofze1/

$scope.showAll = true;
$scope.products = [{
  productId: 2,
  productName: 'asd',
  topic: '123',
  Active: 'true'
}, {
  productId: 3,
  productName: 'asdada',
  topic: '213123',
  Active: 'false'
}]

$scope.toggleReadings = function toggleReadings(product) {
  if ($scope.productToShow == product) {
    $scope.productToShow = undefined;
  } else {
    $scope.productToShow = product;
  }

  $scope.showAll = !$scope.productToShow;

};

With the filter being: ng-show="showAll||productToShow == product"

Sign up to request clarification or add additional context in comments.

Comments

0

This worked using filters: "ng-repeat="... | limitto:selectedRow:rowsToDisplay" while the button click sends row index. Thanks all!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.