Soldeplata Saketos
Soldeplata Saketos

Reputation: 3461

How to update the number of columns in an angular table

I want to change the number of columns on modifying a boolean variable. Check my example (in plnkr):

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('myCtrl', function($scope, $log) {
  $scope.debug = {};
  $scope.fields = [{
      header: "first",
      hideField: !$scope.debug.flag
    },
    {
      header: "second"
    },
    {
      header: "third"
    },
    {
      header: "fourth"
    },
  ];
  $scope.entries = [{
    first: "hello1",
    second: "hello2",
    third: "hello3",
    fourth: "hello4"
  }, ]
  $scope.myBool = true;
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">

<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>

  <div ng-controller="myCtrl">
    <button id="testButton" class='btn btn-danger' ng-click='debug.flag = !debug.flag'><i class="glyphicon glyphicon-hand-right"></i> refreshFields! debug.flag = {{!!debug.flag}}</button>
    <hr>
    <h2 class="label label-info">table 1 with property.hideField = true</h2>
    <table class="table  table-hover">
      <tr>
        <!-- Headers of list-->
        <th ng-repeat="property in fields" ng-if="!property.hideField">{{property.header}}
        </th>
      </tr>
      <tbody>
        <tr ng-repeat="entry in entries">
          <td ng-repeat="property in fields" ng-if="!property.hideField">
            {{entry[property.header]}} {{!!debug.flag}}
          </td>
        </tr>
      </tbody>

    </table>
    <h4 class="label label-info">table 2 with ng-if => property.hideField = false</h4>
    <table class="table  table-hover">
      <tr>
        <!-- Headers of list-->
        <th ng-repeat="property in fields" ng-if="property.hideField">{{property.header}}
        </th>
      </tr>
      <tbody>
        <tr ng-repeat="entry in entries">
          <td ng-repeat="property in fields" ng-if="property.hideField">
            {{entry[property.header]}} {{!!debug.flag}}
          </td>
        </tr>
      </tbody>

    </table>
    <h2 class="label label-info">table 3 without ng-if</h2>
    <table class="table  table-hover">
      <tr>
        <!-- Headers of list-->
        <th ng-repeat="property in fields">{{property.header}}
        </th>
      </tr>
      <tbody>
        <tr ng-repeat="entry in entries">
          <td ng-repeat="property in fields">
            {{entry[property.header]}} {{!!debug.flag}}
          </td>
        </tr>
      </tbody>

    </table>
  </div>
</body>

</html>

How to reproduce it:

Click on the red button and the flag will toggle from false to true.

Expected behavior:

Upvotes: 1

Views: 525

Answers (2)

Sachet Gupta
Sachet Gupta

Reputation: 837

Changing the value of $scope.debug.flag won't change the value of hideField. Because, it has already been initialized at the time of controller load. The workaround you can apply here is bind that hideField to a method and evaluate that in your ng-if. Sample below.

JS:

 $scope.fields = [{
    header: "first",
    hideField: function() {
      return !$scope.debug.flag;
    }
  }, {
    header: "second"
  }, {
    header: "third"
  }, {
    header: "fourth"
  }, ];

HTML:

<h2 class="label label-info">table 1 with property.hideField = true</h2>
<table class="table  table-hover">
  <tr>
    <!-- Headers of list-->
    <th ng-repeat="property in fields" ng-if="!property.hideField()">{{property.header}}
    </th>
  </tr>
  <tbody>
    <tr ng-repeat="entry in entries">
      <td ng-repeat="property in fields" ng-if="!property.hideField()">
        {{entry[property.header]}} {{!!debug.flag}}
      </td>
    </tr>
  </tbody>
</table>

This is not a clean solution though. But, still will solve your problem.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691755

Your heading would become visible if you modified the value of its hideField property. But you're not doing that. You're modifying the value of $scope.debug.flag.

The fact that hideField was initialized with the value of $scope.debug.flag won't magically change hideField every time you change $scope.debug.flag.

Just like if you do

var a = 1;
var b = a;
a = 42;

The value of b will still be 1. Not 42.

Upvotes: 1

Related Questions