3
votes

I have some HTML table on the UI which is created dynamically. There is a condition in which when user will click on a button in a table row then that button will hide itself and some div element will be displayed.I have used ng-show and ng-hide property for that. But it is not working as desired.

Table :

Id   Column1     Column2    Action
1    somevalue  somevalue  <Button>
2    somevalue  somevalue  <Button>

Html of Button Element :(where Id is table first column value)

<button ng-show="hidepenality' + Id + '" type="button" class="btn btn-primary btn-xs" ng-model="btnChangePenality" ng-click="ChangePenalityButton(' + Id + ')" >Change Penality</button>

Html of radio button div : (where Id is table first column value)

<div ng-hide="hidepenality'+Id+'"><label class="c-radio" data-ng-repeat="panalityType in penalityTypeList"><input type="radio" name="typepenality" data-ng-model="typepenality.Id" data-ng-value="{{panalityType.Id}}" /><span>{{panalityType.Type}}</span></label> </div>

Now, when I am clicking on first row button then logic should only hide first row button and only display first row radio div (which is by default hide). Below is my logic :

  $scope.ChangePenalityButton = function (Id) {

                var scope = $parse('hidepenality' + Id)
                scope.assign($scope, false);

        }

But when I am clicking on first row button then button is hiding for both rows, when it should just for first row as per the logic.

Please help!!!!

1
you should take a look at the $compile service docs.angularjs.org/api/ng/service/$compileelasticrash

1 Answers

3
votes

It because ng-hide="hidepenality'+Id+'" is not correct angular expression. I don't think angular will be able to parse it. You should do it like in snipper below. Basically setting flag to every row and then just changing this flag value from true to false and so on.

angular.module('app', []);

angular.module('app').controller('Example', function () {
  this.rows = [
    {name: 'blah1', buttonShown: true},
    {name: 'blah2', buttonShown: true},
    {name: 'blah3', buttonShown: true}
  ];
});
table {
  border: 1px solid black;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>

<div ng-app="app" ng-controller="Example as Example">
  <table>
    <tr ng-repeat="row in Example.rows">
      <td>{{row.name}}</td>
      <td>
        <button ng-show="row.buttonShown" ng-click="row.buttonShown = false">hide</button>
        <div ng-hide="row.buttonShown">
          some div <br>
          <button ng-click="row.buttonShown = true">show</button>
        </div>
      </td>
    </tr>
  </table>
</div>

Edit: To answer your comment, that is interesting cos it sure fails here:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app>
  <button ng-click="hidepenality'+Id+'">error here</button>
</div>

As for dynamic data, it does not matter how array was created, you can add property to each value if you wish so. There is other solution if you don't want to do that, under assumption that each row has unique id, you can create flags object on controller and use it to keep track of show/hide flags.

angular.module('app', []).controller('Example', function () {
  this.flags = {};
  
  this.rows = [
    {name: 'blah1', id: 102},
    {name: 'blah2', id: 4},
    {name: 'blah3', id: 3}
  ];
});
table {
  border: 1px solid black;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>

<div ng-app="app" ng-controller="Example as Example">
  <table>
    <tr ng-repeat="row in Example.rows">
      <td>{{row.name}}</td>
      <td>
        <button ng-hide="Example.flags[row.id]" ng-click="Example.flags[row.id] = true">hide</button>
        <div ng-show="Example.flags[row.id]">
          some div <br>
          <button ng-click="Example.flags[row.id] = false">show</button>
        </div>
      </td>
    </tr>
  </table>
</div>