var app = angular.module('myCart', []);


<!DOCTYPE html>
<html ng-app="myCart">
  <head>
    <meta charset="utf-8" />
    <title>Shopping Cart module</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
    <script src="app.js"></script>
    <script src="cartService.js"></script>
    <script src="cartCtrl.js"></script>
  </head>

  <body ng-controller="CartCtrl" id="container">
    <div class="table container-margin">
      <div class="row" id="title">
        <div class="normal-view data divider-bottom">
           <div class="">
              <h1>Your Shopping Bag</h1>
          </div>
        </div>
        <div class="small-device-view thick-divider-bottom spacing">
          <div class="data col8 align-left">
              Your Shopping Bag
          </div>
          <div class="data col2 align-right" >
            {{totalItems}} ITEMS
          </div>
        </div>
      </div>
        <div class="row">
          <div class="normal-view table thick-divider-bottom spacing">
            <div class="row ">

                <div class="data col7 align-left" > {{totalItems}} ITEMS</div>
                <div class="data col1">SIZE</div>
                <div class="data col1">QTY</div>
                <div class="data col1">PRICE</div>

            </div>
          </div>
        </div>
      <div class="row" ng-repeat="prod in prods" >
        <div class="table" ng-class="{'thick-divider-bottom':$last,'divider-bottom':!$last}">
          <div class="row " >
            <div class="data col3 align-left">
            <img ng-src={{prod.p_img}} alt="prod.p_name"/>
            
            </div>
            <div class="data col7 valign-middle">
              <div class="table">
                <div class="row prod-spec">
                  <div class="data col6 align-left">
                    <div class="uppercase">{{prod.p_variation}}  {{prod.p_name}}</div>
                    <div class="dim">Style #: {{prod.p_style}}</div>
                    <div class="dim">Color: {{prod.p_selected_color.name}} </div>
                    <div class="dim small-device-view uppercase">Size: {{prod.p_selected_size.code}}</div>
                    <div class="small-device-view spacing">QTY:<input type="text" class="qty" size="1" ng-model="prod.p_quantity" ng-change="reCalculate(prod.p_quantity,$index)"/></div>
                    <div class="small-device-view spacing big-font"><span>{{prod.c_currency}}</span><span ng-bind="prod.p_quantity * prod.p_price"></span></div>
                  </div>
                  <div class="normal-view data col1 uppercase">{{prod.p_selected_size.code}}</div>
                  <div class="normal-view data col1"><input type="text" class="qty" size="1" ng-model="prod.p_quantity" ng-change="reCalculate(prod.p_quantity,$index)"/></div>
                  <div class="normal-view data col2" ><span>{{prod.c_currency}}</span><span ng-bind="prod.p_quantity * prod.p_price"></span></div>
                </div>
                <div class="row normal-view">
                  <div class="dim data col5 align-left">EDIT | X Remove | Save For Later</div>
                </div>
              </div>
            </div>
          </div>
          <div class="small-device-view row spacing">
            <div class="dim data col10 align-left">EDIT | X Remove | Save For Later</div>
          </div>
        </div>
        <div class= "normal-view" ng-if="$last">
         <div id="left-section">
           <p><b>Need help or have questions?</b></p>
           <p>Call Customer Service <br/>
           at 1-800-555-5555</p>
           <p><a href="#">Chat with one of our stylists</a></p>
           <p><a href="#">See return & Exchange Policy</a></p>
         </div>
         <div id="right-section" class="container-margin">
           <div class="table ">
             <div class="row promo-code spacing">
               <div class="data col4 align-left ">
                 Enter Promotion code or Gift Card
               </div>
               <div class="data col4">
                 <input type="text" placeholder="code" ng-model="code" />
               </div>
               <div class="data col2">
                 <button class="btn" ng-click="applyCode(code)">APPLY</button>
               </div>
             </div>
             <div class="row spacing"> 
                <div class="data col4 align-left ">
                  <p>SUBTOTAL</p>
                </div>
                <div class="data col4 ">
                </div>
                <div class="data col4" ng-bind="'$' + subTotal">
                </div>
             </div>
             <div class="row spacing"> 
                <div class="data col4 align-left ">
                  <p ng-show="discount > 0">PROMOTION CODE <b>{{code}}</b> APPLIED</p>
                  <p ng-show="discount === 0">NO PROMOTION CODE APPLIED</p>
                </div>
                <div class="data col4 ">
                </div>
                <div class="data col4" ng-bind="'-$'+ discount">
                </div>
             </div>
             <div class="row divider-bottom spacing"> 
                <div class="data col4 align-left ">
                  <p>ESTIMATED SHIPPING*</p>
                  <p>You Qualify for for Free shipping,<br/>
                  because your order is over $50*</p>
                </div>
                <div class="data col4 ">
                </div>
                <div class="data col4 ">
                  FREE
                </div>
             </div>
             <div class="row thick-divider-bottom spacing"> 
                <div class="data col4 align-left ">
                  <p>ESTIMATED TOTAL</p>
                  <p>Tax will be applied during checkout</p>
                </div>
                <div class="data col4 ">
                </div>
                <div class="data col4" ng-bind="'$' + estTotal">
                </div>
             </div>
             <div class="row spacing"> 
                <div class="data col4">
                </div>
                <div class="data col4 ">
                  <a href="#">CONTINUE SHOPPING</a>
                </div>
                <div class="data col4 ">
                  <input type="button" value="CHECKOUT" class="btn"/>
                </div>
             </div>
           </div>
           <p class="align-right">
             <img src="http://imgur.com/bqcZgOZ.jpeg" alt="secure-checkout">Secure checkout.
             Shopping is always safe and secure
           </p>
         </div>
        </div>
        <div class="small-device-view " ng-if="$last">
          <div class="table ">
            <div class="row ">
              <div class="data big-font extra-spacing">ENTER PROMOTION CODE OR GIFT CARD</div>
            </div>
            <div class="row data extra-spacing">
              <input type="text" placeholder="code" ng-model="code" />&nbsp;&nbsp;
              <button class="btn" ng-click="applyCode(code)">APPLY</button>
            </div>
          </div>
          
          <div class="table ">
             <div class="row extra-spacing"> 
                <div class="data col6 align-left ">
                  <p>SUBTOTAL</p>
                </div>
                <div class="data col4" ng-bind="'$' + subTotal">
                </div>
             </div>
             <div class="row extra-spacing"> 
                <div class="data col6 align-left ">
                  <p ng-show="discount > 0">PROMOTION CODE <b>{{code}}</b> APPLIED</p>
                  <p ng-show="discount === 0">NO PROMOTION CODE APPLIED</p>
                </div>
                <div class="data col4" ng-bind="'-$'+ discount">
                </div>
             </div>
             <div class="row divider-bottom extra-spacing"> 
                <div class="data col6 align-left ">
                  <p>ESTIMATED SHIPPING*<br/>
                  <span class="dim">You Qualify for for Free shipping,<br/>
                  because your order is over $50*</span> </p>
                </div>
                <div class="data col4 ">
                  FREE
                </div>
             </div>
             <div class="row  spacing"> 
                <div class="data col6 align-left ">
                  <p>ESTIMATED TOTAL<br/>
                  <span class="dim">Tax will be applied during checkout</span></p>
                </div>
                <div class="data col4" ng-bind="'$' + estTotal">
                </div>
             </div>
            </div>
            <div class="table">
             <div class="row extra-spacing"> 
                <div class="data col4 ">
                  <input  type="button" value="CHECKOUT" class="btn"/>
                </div>
             </div>
             <div class="row extra-spacing">
                <div class="data col10 ">
                  <a href="#">CONTINUE SHOPPING</a>
                </div>
             </div>
             <div class="row extra-spacing">
                <div class="data col10 ">
                  <p>Secure checkout.
             Shopping is always safe and secure</p>
                </div>
             </div>
             <div class="row">
                <div class="data col10 ">
                  <img src="http://imgur.com/bqcZgOZ.jpeg" alt="secure-checkout">
                </div>
             </div>
            </div>
           
        </div>
      </div>
    </div>
  </body>
</html>
/* Smartphones (portrait and landscape) -----------*/
@media screen and (max-width : 480px) {
/* Styles */
  #container .table .normal-view {
    display: none;
  }
  
  #container .table .small-device-view {
    display:block;
  }
  
  #container .table .row {
    font-size :10px;
  }
  
  #container #title {
    height :20px;
  }
  
  #container button{
    font-size:10px;
  }

}

.table .row{
  font-family: serif;
  font-size :12px;
}

.normal-view {
  /*display:block;*/
  width:100%;
}

#container .small-device-view {
  display:none;
}

/* Styles for desktops*/
/*@media screen and (min-device-width : 992px) and (max-device-width : 1224px) {
.normal-view {
  display:block;
}

.small-device-view {
  display:none;
}
}
*/

.table {
  display:table;
  width :100%;
}

.table .row {
  display:table-row;
  width :100%;
}

.table .row .data{
  display:table-cell;
  padding-left:3px;
  padding-right:3px;
}

.table .row .col10 {
  width :100%;
}

.table .row .col3 {
  width :30%;
}

.table .row .col6 {
  width :60%;
}

.table .row .col4 {
  width :40%;
}

.prod-image {
  height :200px;
}

.table .row .col2 {
  width :20%;
}

.table .row .col8 {
  width :80%;
}

.table .row .col7 {
  width :70%;
}

.table .row .col1 {
  width :10%;
}

.container-margin {
  margin :10px;
}

.divider-bottom {
  border-bottom :1px solid grey;
}

.thick-divider-bottom {
  border-bottom :3px solid darkgrey;
}

#title {
  height :100px;
}

.table .row .align-left{
  text-align:left;
}

.table .prod-spec{
  height :80px;
}

.data {
  text-align:center;
}

#left-section {
  width: 30%;
  position:absolute;
}

#right-section { 
  left: 30%;
  position:absolute;
}

.table #right-section .promo-code {
  height : 10px;
}

.align-right {
  text-align: right;
}

.spacing {
  padding-top :5px;
  padding-bottom:5px;
}

.extra-spacing {
  padding-top :10px;
  padding-bottom:10px;
}

.table .row .valign-middle {
  vertical-align:middle;
}

.dim {
  color:lightgrey;
}
.big-font {
  font-size:12px;
}
.uppercase {
  text-transform: uppercase;
}

.btn {
  background: #3498db;
  background-image: -webkit-linear-gradient(top, #3498db, #2980b9);
  background-image: -moz-linear-gradient(top, #3498db, #2980b9);
  background-image: -ms-linear-gradient(top, #3498db, #2980b9);
  background-image: -o-linear-gradient(top, #3498db, #2980b9);
  background-image: linear-gradient(to bottom, #3498db, #2980b9);
  -webkit-border-radius: 0;
  -moz-border-radius: 0;
  border-radius: 0;
  font-family: Arial;
  color: #ffffff;
  font-size:12px;
/*padding: 10px 20px 10px 20px;*/
  text-decoration: none;
}

.btn:hover {
  background: #3cb0fd;
  background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
  background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
  text-decoration: none;
}
app.controller('CartCtrl', function($scope,CartService) {
  var noOfProducts =0;
  var priceQtyArr =[];
  
  $scope.prods=[];
  $scope.code="";
  $scope.totalItems =0;
  $scope.subTotal = 0;
  $scope.estTotal = 0;
  $scope.discount = 0;
  
  $scope.reCalculate =function (newQty, index) {
    var priceQtyObj = priceQtyArr[index];
    var prevQty = priceQtyObj.qty;
    var prevTProdPrice = priceQtyObj.price * prevQty;
    var incOrDecQty =0;
    var incOrDecPrice = 0;
    var newTProdPrice = priceQtyObj.price * newQty;
    priceQtyArr[index].qty = newQty;
    incOrDecQty = newQty - prevQty;
    incOrDecPrice = newTProdPrice - prevTProdPrice;  
    
    $scope.totalItems += incOrDecQty; //update total items on qty change
    $scope.subTotal += incOrDecPrice; //updated subtotal on qty change
    $scope.estTotal = $scope.subTotal - $scope.discount ;
  };
  
  $scope.applyCode = function (code) {

      var disc = 0;
      if(code === "magic3"){
        if($scope.totalItems < 3){
          disc = 0;
        }
        else if ($scope.totalItems === 3){
          disc = $scope.subTotal * 0.05;
        }
        else if ($scope.totalItems > 3 && $scope.totalItems <= 6){
          disc = $scope.subTotal * 0.10;
        }else if($scope.totalItems > 10){
          disc = $scope.subTotal * 0.25;
        }
      }
      
      $scope.discount = disc;
      $scope.estTotal = $scope.subTotal - $scope.discount ;
  };
  
  
  function updateTotal (){
    for(var i=0;i<noOfProducts;i++){
        var q = parseInt($scope.prods[i].p_quantity,10);
        var p = parseInt($scope.prods[i].p_price,10);
        $scope.subTotal += p;
  
        var obj = {
          'qty' : q,
          'price': p
        };
        priceQtyArr.push(obj);
        $scope.totalItems += q;
    }
    $scope.estTotal = $scope.subTotal - $scope.discount ;
  }
  
  //fetch the products & its details
  CartService.$getProductsInCart().
      then(function (response){
           //angular.copy(response.data.productsIncart, $scope.prods);
           $scope.prods = response.data.productsInCart;
           noOfProducts = $scope.prods.length;
           updateTotal();
      });
});
{
	"productsInCart": [{
		"p_id": "1",
		"p_name": "cotton tshirt",
		"p_variation": "solid green",
		"p_style": "ms13kt1906",
		"p_img":"http://imgur.com/zGcrz78.jpeg",
		"p_selected_color": {
			"name": "blue",
			"hexcode": "#1169BD"
		},
		"p_selected_size": {
			"name": "small",
			"code": "s"
		},
		"p_available_options": {
			"colors": [{
				"name": "green",
				"hexcode": "#A3D2A1"
			}, {
				"name": "yellow",
				"hexcode": "#F9F8E6"
			}, {
				"name": "red",
				"hexcode": "#ED99A8"
			}],
			"sizes": [{
				"name": "small",
				"code": "s"
			}, {
				"name": "medium",
				"code": "m"
			}, {
				"name": "large",
				"code": "l"
			}, {
				"name": "extra large",
				"code": "xl"
			}]
		},
		"p_quantity": 1,
		"p_originalprice": 11.0,
		"p_price": 11.0,
		"c_currency": "$"
	}, {
		"p_id": "2",
		"p_name": "print girls tee",
		"p_variation": "pink rainbow",
		"p_style": "ms13kt1906",
		"p_img":"http://imgur.com/Hjfrn56.jpeg",
		"p_selected_color": {
			"name": "pink",
			"hexcode": "#F1DDEF"
		},
		"p_selected_size": {
			"name": "small",
			"code": "s"
		},
		"p_available_options": {
			"colors": [{
				"name": "green",
				"hexcode": "#A3D2A1"
			}, {
				"name": "yellow",
				"hexcode": "#F9F8E6"
			}, {
				"name": "pink",
				"hexcode": "#F1DDEF"
			}],
			"sizes": [{
				"name": "small",
				"code": "s"
			}, {
				"name": "medium",
				"code": "m"
			}, {
				"name": "large",
				"code": "l"
			}, {
				"name": "extra large",
				"code": "xl"
			}]
		},
		"p_quantity": 1,
		"p_originalprice": 17.0,
		"p_price": 17.0,
		"c_currency": "$"
	}, {
		"p_id": "3",
		"p_name": "flower pattern shirt",
		"p_variation": "blue",
		"p_style": "ms13kt1906",
		"p_img":"http://imgur.com/EpT67f4.jpeg",
		"p_selected_color": {
			"name": "blue",
			"hexcode": "#1169BD"
		},
		"p_selected_size": {
			"name": "small",
			"code": "s"
		},
		"p_available_options": {
			"colors": [{
				"name": "green",
				"hexcode": "#A3D2A1"
			}, {
				"name": "blue",
				"hexcode": "#1169BD"
			}, {
				"name": "red",
				"hexcode": "#ED99A8"
			}],
			"sizes": [{
				"name": "small",
				"code": "s"
			}, {
				"name": "medium",
				"code": "m"
			}, {
				"name": "large",
				"code": "l"
			}, {
				"name": "extra large",
				"code": "xl"
			}]
		},
		"p_quantity": 1,
		"p_originalprice": 21.0,
		"p_price": 9.0,
		"c_currency": "$"
	}, {
		"p_id": "4",
		"p_name": "check pattern tshirt",
		"p_variation": "mens red",
		"p_style": "ms13kt1906",
		"p_img":"http://imgur.com/G6t80Rc.jpeg",
		"p_selected_color": {
			"name": "red",
			"hexcode": ""
		},
		"p_selected_size": {
			"name": "small",
			"code": "s"
		},
		"p_available_options": {
			"colors": [{
				"name": "green",
				"hexcode": "#A3D2A1"
			}, {
				"name": "yellow",
				"hexcode": "#F9F8E6"
			}, {
				"name": "red",
				"hexcode": "#ED99A8"
			}],
			"sizes": [{
				"name": "small",
				"code": "s"
			}, {
				"name": "medium",
				"code": "m"
			}, {
				"name": "large",
				"code": "l"
			}, {
				"name": "extra large",
				"code": "xl"
			}]
		},
		"p_quantity": 1,
		"p_originalprice": 22.0,
		"p_price": 22.0,
		"c_currency": "$"
	}]
}
app.factory('CartService', function($http) {
  
  var getProducts = function  () { 
       return $http.get('products.json');
  };
  
  
  return {
    $getProductsInCart : getProducts
  };
});
Responsive Shopping cart module using AngularJS 1.5.x
=============

how it works
----------------
+ Entire shopping cart is designed as responsive screen
+ Media queries have been incorporated to support small devices (max-width : 480px) & desktop 
+ Shopping cart contains logic for discount calculation based on promo-code provided

Demo
----------------
[demo @ plunker](http://plnkr.co/edit/TnffNy6WRp2UgY2ixgrc?p=info)