Reputation: 704
Currently have my checkboxes adding and subtracting their costs from my total cost. How can I get my select to do the same? Currently its putting in a default value of 7700.00 when without the select field it is at 0.00. Also noticed my select field is breaking my checkbox function by not subtracting the number off when unchecked.
Updated Fiddle: http://jsfiddle.net/9exaarn2/6/
HTML:
<div ng-app>
<div ng-controller="showCrtl">
<input type="checkbox" name="additionalCoverage" ng-click="cost(150, $event.target.checked)">
<label>Add this coverage $150/YR</label>
<br>
<input type="checkbox" name="additionalCoverage" ng-click="cost(40, $event.target.checked)">
<label>and or this coverage $40/YR</label><br>
<select>
<option disabled selected>Select one...</option>
<option ng-selected="option(200)">add $200/yr</option>
<option ng-selected="option(500)">add $500/yr</option>
</select>
<h1 class="annualCost">TOTAL ANNUAL COST<br>OF HOME WARRANTY</h1>
<span style="color: green; font-size: 45px; line-height: 2;">{{annualCost}}</span>
<br>
</div>
</div>
JS:
function showCrtl($scope) {
$scope.dollarAmmount = 0.00;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
$scope.option = function (amt) {
$scope.dollarAmmount = $scope.dollarAmmount + amt;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
console.log($scope.dollarAmmount)
};
$scope.cost = function (amt, checked) {
amt *= checked ? 1 : -1;
$scope.dollarAmmount = $scope.dollarAmmount + amt;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
console.log($scope.dollarAmmount)
};
}
EDIT: Oops had a typo in my fiddle. Issue still the same...
Upvotes: 3
Views: 1955
Reputation: 4305
It is clear you are thinking with a jQuery mindset. You need to practice thinking the angular way. See this question and answer for some idea on what that is.
First thing, you need to actually model your problem, describing what things are and not so much how things are done. This may seem like splitting hairs. It is not. You should be using ng-model
to track form input, not click handlers.
Here's the controller code you should strive for.. notice how totalCost
is defined as a sum of the coverage costs.. and not some value you are manipulating manually as the user changes your form:
function showCrtl($scope) {
$scope.coverage = [];
$scope.totalCost = function (){
return $scope.coverage.reduce(function(sum, cost){
return sum + parseInt(cost);
},0);
};
}
And here's the template (note that I removed the input names and click handlers... you don't need 'em!):
<input type="checkbox" ng-model="coverage[0]" ng-true-value="150" ng-false-value="0">
<label>Add this coverage $150/YR</label>
<br>
<input type="checkbox" ng-model="coverage[1]" ng-true-value="40" ng-false-value="0">
<label>and or this coverage $40/YR</label><br>
<select ng-model="coverage[2]">
<option disabled selected>Select one...</option>
<option ng-value="200">add $200/yr</option>
<option ng-value="500">add $500/yr</option>
</select>
<h1 class="annualCost">TOTAL ANNUAL COST<br>OF HOME WARRANTY</h1>
<span style="color: green; font-size: 45px; line-height: 2;">
{{totalCost() | currency}}
</span>
Also note the use of currency
. This is called a filter. It is used for formatting a number in the $0.00 format. Formatting is a responsibility typically handled by the view and not the controller or model.
Check out the working fiddle.
If you're interested, we can take things a little further and improve the model more. Do you see how the coverage costs are duplicated in the template (one for display, one in ng-value
)? We can rewrite the controller and view such that the application model (your coverage options) are represented in only one place:
Controller:
function showCrtl($scope) {
$scope.coverageCosts = [];
$scope.totalCost = function (){
return $scope.coverageCosts.reduce(function(sum, cost){
return sum + parseInt(cost);
},0);
};
$scope.primaryCoverageOptions = [150,40];
$scope.specialCoverageOptions = [200, 500];
}
In the future, your coverageOptions
might come from your back end via AJAX ($http.get
) or vary on some schedule. Now that the information has been extracted from your view, you can change it more freely.
Template:
<div ng-app>
<div ng-controller="showCrtl">
<div ng-repeat="option in primaryCoverageOptions">
<label>
<input type="checkbox" ng-model="coverageCosts[$index]" ng-true-value="{{option}}" ng-false-value="0"/>
Add this coverage {{option | currency}}/YR
</label>
</div>
<select ng-model="coverageCosts[2]">
<option disabled selected>Select one...</option>
<option ng-repeat="option in specialCoverageOptions" ng-value="option">
{{option | currency}}
</option>
</select>
<h1 class="annualCost">TOTAL ANNUAL COST<br>OF HOME WARRANTY</h1>
<span style="color: green; font-size: 45px; line-height: 2;">
{{totalCost() | currency}}
</span>
<div>
Selected coverage costs: {{coverageCosts}}
</div>
<br>
</div>
</div>
Now there is no duplicated data in the view... all data comes from the controller. This is good practice.
Upvotes: 2
Reputation: 1069
Here is the solution
<div ng-app>
Add this coverage $150/YR
and or this coverage $40/YR
<select ng-selected="option()" ng-model="sel">
<option disabled selected>Select one...</option>
<option value="200">add $200/yr</option>
<option value="500">add $500/yr</option>
</select>
<h1 class="annualCost">TOTAL ANNUAL COST<br>OF HOME WARRANTY</h1>
<span style="color: green; font-size: 45px; line-height: 2;">{{annualCost}}</span>
<br>
and for your js,
function showCrtl($scope) {
$scope.sel =0;
$scope.dollarAmmount = 0.00;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
$scope.option = function () {
$scope.dollarAmmount = $scope.dollarAmmount + $scope.sel;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
console.log($scope.dollarAmmount)
};
$scope.cost = function (amt, checked) {
amt *= checked ? 1 : -1;
$scope.dollarAmmount = $scope.dollarAmmount + amt;
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
console.log($scope.dollarAmmount)
};
}
Upvotes: 0
Reputation: 5857
You can simply bind a $scope model to select then watch its value.. after every change take differences of new and old value and add it to the totalAmount...
$scope.$watch('selectedValue', function(newValue, oldValue){
$scope.dollarAmmount = $scope.dollarAmmount + (newValue - oldValue);
console.log($scope.dollarAmmount)
$scope.annualCost = "$" + $scope.dollarAmmount + ".00";
})
here is your updated JSFIDDLE...
NOTE!!: You should initialize your variable at your scope otherwise first value f it will be undefined which breaks your algorithm...
$scope.selectedValue = 0;
Upvotes: 0