0

Another angular question:

The aim is to make it so that a value entered within the #quantity input is the taken and times by the item's price, as listed within the controller.

For example, if the price is 99.00 and the user wants a quantity of 2, the result of 99 * 2 is out put in the .total div.

How would I go about creating this?

The HTML I have is as below:

  <input type="number"  min="0" max="10" id="quantity" name="store-quantity" value='1'/>
  <div class="total">
    <!-- Total to be printed here -->
  </div>

A small snippet of my store.controller.js

angular.module('angularStoreApp')
  .controller('StoreCtrl', function ($scope, $http) {
    var item = [
      {
        name:  'Almond Toe Court Shoes, Patent Black',
        price: 99.00,
        category: 'Womens Footware',
        stock: 5,
        canPurchase: true,
        images: [
          "assets/images/yeoman.png",
          "http://billypurvis.co.uk/wp-content/uploads/2015/06/ACTA.png"

        ]
      },
Billy Purvis
  • 245
  • 2
  • 10
  • what is your question here? That's *a lot* of code to ask how to multiply a value. – Claies Jun 15 '15 at 19:25
  • I need to make it so that if a user puts in a quanity of 12 for example, the total will be 12 * whatever the product price is. For example. 2 Suede Shoes, Blue would out put a total of £84.00. – Billy Purvis Jun 15 '15 at 19:27
  • if you mean the line where you have `total(product.price, quantity)`, you didn't show what that function actually does, or where you assign `quantity`. but that should be able to be done inline, i.e. `Total: {{product.price * quantity}}`, since it's a simple computation. – Claies Jun 15 '15 at 19:29
  • the rest of the code doesn't have any relevance to the problem, and actually makes it harder to identify where your question is actually at. I'm ***guessing*** here that the `` is where you expect the user to type a quantity in, so you probably should have `ng-model="quantity"` assigned to it. You probably also will need an ng-model on your `voucher` input as well if you want to retrieve that variable later, or apply a discount based on it.... – Claies Jun 15 '15 at 19:34
  • Hey, I've tried, it's still not working. Let me copy what I've done so far rather than blank. Let me edit the provided code. – Billy Purvis Jun 15 '15 at 19:37
  • you can't really post code of more than a few short statements in comments, you should edit your question with more detail instead. – Claies Jun 15 '15 at 19:38
  • I get you, sorry, I don't often use StackOverflow, and very new to angular. I'll remove what I've posted as it's a mess, I'll put what code I currently have an then ask what method I'd use to complete what I want to be done. Your help is appreciated. – Billy Purvis Jun 15 '15 at 19:46
  • you gutted out too much of your code there however, I still don't see you using `ng-model`, which would allow angular to use that input box as a two way binding. – Claies Jun 15 '15 at 19:53
  • It was intentional, I don't have much of an understanding on what to put. So, if someone would be able to suggest a method, I'll read that code and then apply the same logic to mine. Start afresh as it were. – Billy Purvis Jun 15 '15 at 19:55
  • remember, don't think of angular the same way you think of HTML or JQuery. if you are trying to refer to things like `#mytextbox` in angular, you're doing it wrong. – Claies Jun 15 '15 at 19:56
  • generally trying to have a conversation in comments isn't recommended, but I've been willing to try to help you to formulate a better, more answerable question, and hope it helps with your questions in the future. Your question went from having **too much** detail to having **not enough** detail. you might want to take a read at http://stackoverflow.com/help/mcve for advice on creating a Minimal, Complete, and Verifiable Example. – Claies Jun 15 '15 at 20:00
  • Thanks, I'll take a read. I noticed that, though, I'm unable to start a chat due to a low rep. Apologies. – Billy Purvis Jun 15 '15 at 20:01
  • I added an answer, which has about the amount of code that should have been presented in the question. With too much code, the area where the problem is at gets lost. With not enough code, you get answers which are harder to adapt to your issue. **Definitely NOT** suggesting the other answer is wrong, but this should show the contrast in detail. – Claies Jun 15 '15 at 20:25

2 Answers2

1

I created a plunker with a sample based on the code that was originally in the question, with a few augmentations.

Here is the relevant portion of the code:

<div ng-repeat="product in products" ng-show="product.canPurchase " class="item-panel">
  <div class="pull-left full product-info">
    <h1>{{product.name | limitTo: 20}}...</h1>
    <h2 class="pull-left full">{{product.price | currency}}</h2>
    <div ng-hide="{{product.stock <= 0}}">
      <input class="pull-left voucher-input" placeholder="Voucher Code" />

      <input type="number" ng-model="quantity" max="{{product.stock}}"/>
      <input type="submit" value="Add to Cart" />
      <div class="total">
        Total:{{ product.price * quantity | currency }}
      </div>
    </div>
  </div>
</div>

Note that I first started by adding ng-model="quantity" to the input field, providing quantity as a variable that can be accessed. Because each iteration of ng-repeat creates a new scope for that block, there will be a quantity variable scoped to each product in the repeat.

Next, I added the max="{{product.stock}}" to the input, to demonstrate that you can bind a property on your object to a plain HTML element item. If you enter a quantity greater than product.stock, then quantity is set to NaN.

Lastly, I added the actual calculation Total:{{ product.price * quantity | currency }}. Here, I used the currency filter, which also ensures that if quantity is 0 or NaN, the display is blank rather than NaN.

Claies
  • 22,124
  • 4
  • 53
  • 77
  • Hello - it worked a treat. Just a couple of questions to make sure I understand this correctly. ng-mode="quantity" is allowing access to the quantity property and due to the ng-repeat, a new scope with quantity varible is on each product? I still need to grasp the understanding of scope fully. I understand what you're doing in regards to using the property binded to the max on the HTML, I didn't think of doing that. Very much appreciated. I can also see what you mean with being concise with my code. Thank you very much. – Billy Purvis Jun 15 '15 at 20:37
  • because of how prototype inheritance works in relation to angular (this article http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs is a great read, btw), and the fact that `ng-repeat` gives each item in the collection a scope (https://docs.angularjs.org/api/ng/directive/ngRepeat#!), there are multiple `quantity` variables, each ***only*** accessible from within the same `
    ` that created it.
    – Claies Jun 15 '15 at 20:52
  • I'll read those documents. Ah, I understand how it's working now. Hence how it gets the right price for each item listed, because it's only able to access the price from the respective repeated item. Thank you! I think my next job is to create a new view which is the shopping basket and linking the items to it and also add in the discount vouchers. Neither of which I have a clue, is there documentation to help me with such a request? – Billy Purvis Jun 15 '15 at 21:00
  • for that, you'll need a function defined in the controller that can accept the `product`, `quantity`, and `Voucher code`; you'll probably want to pass those values to the server and do your stock movement there rather than on the client, so you don't have two people try to buy the last item in stock at the same time. – Claies Jun 15 '15 at 21:12
0

Try this code:

<div ng-app="angularStoreApp" ng-controller="StoreCtrl as storeCtrl">
    <input type="number"  min="0" max="10" id="quantity" name="store-quantity" value='1' ng-model="quantity"/>
    <div class="total">
        {{ storeCtrl.item[0].price * quantity }}
    </div>
</div>

and

angular.module('angularStoreApp', [])
    .controller('StoreCtrl', function ($scope, $http) {
        $scope.quantity = 0;
        this.item = [
            {
                name:  'Almond Toe Court Shoes, Patent Black',
                price: 99.00,
                category: 'Womens Footware',
                stock: 5,
                canPurchase: true,
                images: [
                    "assets/images/yeoman.png",
                    "http://billypurvis.co.uk/wp-content/uploads/2015/06/ACTA.png"
                ]
           }
       ];
  })

Replace itemId with your item's id (in your case, 0)

See this fiddle: https://jsfiddle.net/pk5qfdyx/

Warning! If the number entered is over 10 then it will result in null.

Nathan
  • 1,321
  • 1
  • 18
  • 32