I want to calculate taxes in relation with a user-input that correspond to the price.
I have no problem when I don't use ng-repeat. But I can't figure out how to make it works with ng-repeat. For information, the code below refers to an invoice controller where I add items to the invoice.
Here is what I have:
Controller
App.controller('FacturesSoloController', function($scope, $stateParams, Facture ) {
$scope.factureId = $stateParams.factureId;
Facture.get({ id: $stateParams.factureId }, function(data) {
$scope.facture = data;
$scope.ajouterItem = function(){
$scope.facture.items.push({});
}
});
$scope.calculTps = function() {
$scope.item.tps = $scope.item.prix*5/100;
};
$scope.calculTvq = function() {
$scope.item.tvq = $scope.item.prix*9.975/100;
};
$scope.calculGrandTotal = function() {
$scope.item.grandtotal = parseFloat($scope.item.prix)+parseFloat($scope.item.tps)+parseFloat($scope.item.tvq);
};
});
Here is my HTML file
<table class="table">
<thead>
<tr>
<th><strong>Description</strong></th>
<th class="text-right"><strong>Prix</strong></th>
<th class="text-right"><strong>TPS</strong></th>
<th class="text-right"><strong>TVQ</strong></th>
<th class="text-right"><strong>Grand Total</strong></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in facture.items">
<td class="bold" width="50%">
<input type="text" class="form-control" name="description" id="description" ng-model="item.description"></td>
<td class="text-right">
<input type="text" class="form-control" name="prix" id="prix" ng-model="item.prix"></td>
<td class="text-right">
<input type="text" class="form-control" name="tps" id="tps" ng-model="item.tps" value="{{calculTps()}}"></td>
<td class="text-right">
<input type="text" class="form-control" name="tvq" id="tvq" ng-model="item.tvq" value="{{calculTvq()}}"></td>
<td class="text-right">
<input type="text" class="form-control" name="grandtotal" id="grandtotal" ng-model="item.grandtotal" value="{{calculGrandTotal()}}">
</td>
</tr>
<tr>
<td class="bold"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right">Grand Total</td>
</tr>
</tbody>
</table>
And here is what {{facture.items | json}} returns
[
{
"id": 1,
"facture_id": 10200,
"description": "Item numéro 1",
"prix": "15.00",
"tps": "0.75",
"tvq": "1.50",
"grandtotal": "17.25",
"created_at": "2015-02-21 15:07:18",
"updated_at": "2015-02-21 15:07:18"
},
{
"id": 2,
"facture_id": 10200,
"description": "Deuxième item quoi",
"prix": "135.00",
"tps": "6.75",
"tvq": "13.47",
"grandtotal": "155.22",
"created_at": "2015-02-21 15:07:18",
"updated_at": "2015-02-21 15:07:18"
}
]
So, I would like the "tps" and the "tvq" to calculate automaticly when I enter a number in the "prix" input. I wonder what is wrong.
In your javascript you still need to refer to 'item' as part of the 'facture' array. The controller doesn't know what '$scope.item' is. You can use '$index' to call a function which will do your calculations for each element in the array.
App.controller('FacturesSoloController', function($scope, $stateParams, Facture ) {
$scope.factureId = $stateParams.factureId;
Facture.get({ id: $stateParams.factureId }, function(data) {
$scope.facture = data;
$scope.ajouterItem = function(){
$scope.facture.items.push({});
}
});
$scope.calculTps = function(i) {
$scope.facture.items[i].tps = $scope.facture.items[i].prix*5/100;
};
$scope.calculTvq = function(i) {
$scope.facture.items[i].tvq = $scope.facture.items[i].prix*9.975/100;
};
$scope.calculGrandTotal = function(i) {
$scope.facture.items[i].grandtotal = parseFloat($scope.facture.items[i].prix)+parseFloat($scope.facture.items[i].tps)+parseFloat($scope.facture.items[i].tvq);
};
$scope.doCalculations = function(i) {
$scope.calculTvq(i);
$scope.calculTps(i);
$scope.calculGrandTotal(i);
}
});
and your HTML
<table class="table">
<thead>
<tr>
<th><strong>Description</strong></th>
<th class="text-right"><strong>Prix</strong></th>
<th class="text-right"><strong>TPS</strong></th>
<th class="text-right"><strong>TVQ</strong></th>
<th class="text-right"><strong>Grand Total</strong></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in facture.items">
<td class="bold" width="50%">
<input type="text" class="form-control" name="description" id="description" ng-model="item.description"></td>
<td class="text-right">
<input type="text" class="form-control" name="prix" id="prix" ng-model="item.prix" ng-change="doCalculations($index)></td>
<td class="text-right">
<input type="text" class="form-control" name="tps" id="tps" ng-model="item.tps"></td>
<td class="text-right">
<input type="text" class="form-control" name="tvq" id="tvq" ng-model="item.tvq"></td>
<td class="text-right">
<input type="text" class="form-control" name="grandtotal" id="grandtotal" ng-model="item.grandtotal">
</td>
</tr>
<tr>
<td class="bold"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right">Grand Total</td>
</tr>
</tbody>
</table>
https://docs.angularjs.org/api/ng/directive/ngRepeat https://docs.angularjs.org/api/ng/directive/ngChange
UPDATE:
You should also use ngChange to call both calculation functions each time the 'prix' is updated