jaylenne jaylenne -4 years ago 45
Javascript Question

Calling a function using ng-init inside ng-repeat only gets the result of the last item in the loop

I am trying to change a progress bar content for each line in my table. To do so I used ng-init inside ng-repeat here is my code :

The view :

<tr ng-repeat-start="p in projetsListe" ng-init={{progressBar($index)}}>
<td>
<button class="btn btn-info btn-sm" ng-click="p.expanded = !p.expanded" expand data-toggle="collapse" id="{{p.IdProjet}}" data-target=".{{p.IdProjet}}">
<span ng-bind="p.expanded ? '-' : '+'"></span>
</button>
</td>
<td>{{p.NomProjet}}</td>
<td>{{p.Responsable}}</td>
<td>{{trestant[$index]}}</td>
<td><div class="progress">
<div class="progress-bar progress-bar-danger progress-bar-striped active" role="progressbar" aria-valuenow="40" id="pg1" aria-valuemin="0" aria-valuemax="100"><label id="l1"></label>
</div>
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="40" id="pg2" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<label style="font-size :10px"><i class="fa fa-circle" style ="color : #df6d69"></i> Temps Passé : {{tpasse[$index]}}h</label>
&nbsp &nbsp
<label style="font-size :10px"><i class="fa fa-circle" style ="color : green"></i> Temps Prévu : {{tprev[$index]}}h</label>
</td>
</tr>


My function :

$scope.progressBar= function(i){
var tpa;
var p1 = document.getElementById('pg1');
var p2 = document.getElementById('pg2');
var l1 = document.getElementById('l1');
tpa = ($scope.tpasse[i]*100)/$scope.tprev[i];
if(tpa<=100){
p1.style.width = tpa + '%';
p2.style.width = 100-tpa + '%';
l1.innerHTML = " ";
}
else{
p1.style.width = '100' +'%';
l1.innerHTML = "Attention : Temps prévu dépassé !";
}
};


In the result I only get the data of the last line of the table and it appears in the first line:

enter image description here

This result should appear in the second line which is now empty, while the first one should have different result. Any suggestions on how to solve this issue ?

Here is a plunker that illustrates this problem : https://plnkr.co/edit/nGxqMOPejKMINb89Ewwx?p=preview

Answer Source

The main issue with you cod is that you have same id for different elements. And that is not allowed so only your progress bars are not coming properly. Below is the code that solves your problem. But what i would suggest is that there are other issues as well with your code for eg you are using interpolation with ng-init={{}progressBar($index)} but this will throw error as progressBar returns nothing. I think you need to review you code properly.

// Code goes here
var myApp = angular.module('myApp', []);

myApp.controller('Ctrl', function ($scope) {

$scope.tpasse = ['5049','26','100'];
$scope.tprev = ['688','336','400'];

$scope.projetsListe = [
    {
      "NomProjet" : "Project1",
      "ResponsableApitech" : "Jean"

    },

    {
     "NomProjet" : "Project2", 
     "ResponsableApitech" : "Edward"

    },

    {
     "NomProjet" : "Project2", 
     "ResponsableApitech" : "Edward"

    }
];
console.log($scope.projetsListe);

 $scope.progressBar= function(i){   
        var tpa;
        var p1 = document.getElementById('pg'+i);
        var p2 = document.getElementById('pgb'+i);
        var l1 = document.getElementById('l'+i);

        tpa = ($scope.tpasse[i]*100)/$scope.tprev[i];
           if(tpa<=100){
             p1.style.width =  tpa + '%';
             p2.style.width =  100-tpa + '%';
             l1.innerHTML = " ";
           }
           else{
             p1.style.width = '100' +'%';   
             l1.innerHTML = "Attention : You have reached the limits!";
           }  
 };
});

<html ng-app="myApp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
  <link data-require="bootstrap-css" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
  <link data-require="bootstrap@*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
  <script data-require="jquery" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script data-require="bootstrap" data-semver="4.0.5" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
  <link href="style.css" rel="stylesheet" />
  <script src="script.js"></script>
</head>

<body>
  <div ng-controller="Ctrl">

    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Nom</th>
          <th>Responsable</th>
          <th>Progress</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="p in projetsListe track by $index">
          <td>{{p.NomProjet}}</td>
          <td>{{p.ResponsableApitech}}</td>
          <td>
            <div class="progress" ng-init="{{progressBar($index)}}">
              <div class="progress-bar progress-bar-danger " role="progressbar" aria-valuenow="40" id="pg{{$index}}" aria-valuemin="0" aria-valuemax="100">
                <label id="l{{$index}}"></label>
              </div>
              <div class="progress-bar progress-bar-success progress-bar-striped " role="progressbar" aria-valuenow="40" id="pgb{{$index}}" aria-valuemin="0" aria-valuemax="100"></div>
            </div>
            <label style="font-size :10px"><i class="fa fa-circle" style="color : #df6d69"></i> Temps Passé : {{tpasse[$index]}}h</label> &nbsp; &nbsp;
            <label style="font-size :10px"><i class="fa fa-circle" style="color : green"></i> Temps Prévu : {{tprev[$index]}}h</label>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</body>

</html>

Updated Plunker

Hope it helps :)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download