3

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...

3
  • It would appear you are thinking with a jQuery mindset. I'll post a jsfiddle in a few minutes to show you the angular way to achieve your goal. Commented May 19, 2015 at 21:58
  • Awesome! I will wait patiently... :P Commented May 19, 2015 at 21:59
  • 1
    You should read this question and answer. I think it will help. Commented May 19, 2015 at 21:59

3 Answers 3

2

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.

Updated fiddle

Sign up to request clarification or add additional context in comments.

6 Comments

one thing that I notice right off the bat. There is no longer a $ or a decimal point value which I need both. (This may be something I can solve on my own just pointing out that they are no longer there and needed for my situation)
in your html, to display $ and .00, just add the currency filter, see this: angularjs docs..the View should handle this type of formatting, not the Model or Controller.
@Shehryar didn't think of that. I was able to easily add it back using the controller but that might work better I will look into that. Thanks everyone who has helped! :D
@Shehryar, good catch. Updated the answer to include use of the currency filter.
@JonathanWilson Just added your code to my website it works GREAT!!! thanks again.
|
0

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;

2 Comments

This looks to be what I was looking for! will test before marking answer correct just in case.
This is a duct tape solution. @LandonCall needs help thinking the angular way
0

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)
};

}

1 Comment

Perhaps you made it work but this is not a good angular solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.