A Simple Shopping List and Inventory built with AngularJS
A Pen by Akinyele Oluwatosin Akintayo on CodePen.
| <html ng-app="root"> | |
| <div class="container" ng-controller="index"> | |
| <div class="box margin-right" id="shopping-list"> | |
| <h1>My Shopping List</h1> | |
| <div id="errorMessage"><i class="icon-cross"></i>Please enter all inputs!</div> | |
| <div id="successMessage"><i class="icon-checkmark"></i>Item added to shopping list!</div> | |
| <div class="half margin-right"> | |
| <input type='text' class="searchButton" placeholder='Item Name' ng-model="itemName" autofocus required> | |
| </div> | |
| <div class="half margin-right"> | |
| <input type='number' class="searchButton margin-right" placeholder='Quantity' ng-model="itemQuantity" required> | |
| </div><div class="dollar half"> | |
| <span>$</span> | |
| <input type='number' class="searchButton" placeholder='Price (each)' ng-model="itemPrice" required> | |
| </div> | |
| <button id="addItem" ng-click="addItem()">Add Item</button> | |
| <div class="list"> | |
| <table border="0" cellspacing="0"> | |
| <tr class="table-header"> | |
| <td></td> | |
| <td class="left">Item Name</td> | |
| <td>Quantity</td> | |
| <td class="center">Price</td> | |
| <td class="center">Delete</td> | |
| </tr> | |
| <tr ng-repeat="item in list | orderBy: '-checked':true"> | |
| <td><input ng-show="!item.checked" ng-checked="item.checked" ng-click="add(item, list)" type='checkbox' checklist-value="item.checked"></td> | |
| <td ng-class="{selected: item.checked==true}">{{item.name}}</td> | |
| <td ng-class="{selected: item.checked==true}" class="center">{{item.quantity}}</td> | |
| <td ng-class="{selected: item.checked==true}">{{item.price | currency}}</td> | |
| <td><i class="icon-cross delete" ng-click="remove(item)"><svg width="24" height="24" viewBox="0 0 24 24"> | |
| <path d="M22,3H7C6.31,3 5.77,3.35 5.41,3.88L0,12L5.41,20.11C5.77,20.64 6.31,21 7,21H22A2,2 0 0,0 24,19V5A2,2 0 0,0 22,3M19,15.59L17.59,17L14,13.41L10.41,17L9,15.59L12.59,12L9,8.41L10.41,7L14,10.59L17.59,7L19,8.41L15.41,12"></path> | |
| </svg></i></td> | |
| </tr> | |
| </table> | |
| <div ng-hide="list.length" class="center">Your shopping list is empty.</div> | |
| <div class="cost cf"> | |
| <span class="left">SubTotal Cost:</span> | |
| <span class="right" ng-class="{total: length!==0}">{{getTotal() | currency}}</span> | |
| </div> | |
| <button class="clear" ng-click="clearAll(list)">Clear Shopping List</button> | |
| </div> | |
| </div> | |
| <!--<div class="box" id="inventory"> | |
| <h1>Inventory</h1> | |
| <div class="list"> | |
| <table border="0" cellspacing="0"> | |
| <div ng-hide="inventory.length" class="center">Your inventory is empty.</div> | |
| <tr ng-repeat="item in inventory"> | |
| <td>{{item.name}}</td> | |
| <td class="center">{{item.quantity}}</td> | |
| <td class="center">{{item.price | currency}}</td> | |
| <td><i class="icon-cross delete" ng-click="removeInventory(item)"></i></td> | |
| </tr> | |
| </table> | |
| <button class="clear" ng-click="clearAll(inventory)">Clear Inventory</button> | |
| </div> | |
| </div>--> | |
| </div> | |
| </html> | |
| var shoppingList = angular.module("root", []); | |
| shoppingList.controller("index", ["$scope", function ($scope){ | |
| $scope.itemName; | |
| // $scope.itemShop; | |
| $scope.itemQuantity; | |
| $scope.itemPrice; | |
| var success = document.getElementById('successMessage'); | |
| var error = document.getElementById('errorMessage'); | |
| $scope.selection = []; | |
| $scope.list = [ | |
| {name: 'Milk', quantity: 1, price: 2.65, checked: false}, | |
| {name: 'Bread', quantity: 1, price: 2.15, checked: false}, | |
| {name: 'Eggs', quantity: 1, price: 1.75, checked: false}, | |
| {name: 'Chow Mein', quantity: 1, price: 3.10, checked: false}, | |
| {name: 'Bacon', quantity: 1, price: 2.20, checked: false}, | |
| {name: 'Yoghurt', quantity: 6, price: 3.10, checked: false}, | |
| {name: 'Chocolate', quantity: 6, price: 3.10, checked: false} | |
| ]; | |
| $scope.getTotal = function(){ | |
| var total = 0; | |
| for(var i = 0; i < $scope.list.length; i++){ | |
| total += $scope.list[i].price; | |
| } | |
| return total; | |
| }; | |
| $scope.inventory = [ | |
| {name: 'Milk', shop:'CVS', quantity: 1, price: 2.65}, | |
| {name: 'Bread', shop: 'CVS', quantity: 1, price: 2.15}, | |
| {name: 'Eggs', shop: 'CVS', quantity: 1, price: 1.75}, | |
| ]; | |
| $scope.remove = function(item) { | |
| var index = $scope.list.indexOf(item) | |
| $scope.list.splice(index, 1); | |
| } | |
| $scope.removeInventory = function(item) { | |
| var index = $scope.inventory.indexOf(item) | |
| $scope.inventory.splice(index, 1); | |
| } | |
| $scope.clearAll = function(list){ | |
| var length = list.length; | |
| list.splice(0, length); | |
| }; | |
| $scope.addItem = function() { | |
| if($scope.itemName && $scope.itemQuantity && $scope.itemPrice){ | |
| $scope.list.push({name: $scope.itemName, quantity: $scope.itemQuantity, price: $scope.itemPrice * $scope.itemQuantity, checked: false}); | |
| $scope.itemName = ''; | |
| //$scope.itemShop = ''; | |
| $scope.itemQuantity = ''; | |
| $scope.itemPrice = ''; | |
| success.style.display = 'block'; | |
| var timer = setTimeout(function(){ | |
| success.style.display = 'none'; | |
| }, 2000); | |
| } | |
| } | |
| $scope.add = function(item){ | |
| var item = $scope.list.indexOf(item); | |
| $scope.inventory.push($scope.list[item]); | |
| $scope.list[item].checked = true; | |
| } | |
| }]); |
| <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script> |
A Simple Shopping List and Inventory built with AngularJS
A Pen by Akinyele Oluwatosin Akintayo on CodePen.
| @import "compass/css3"; | |
| *, *:before, *:after { | |
| @include box-sizing(border-box); | |
| } | |
| $red: #fb887c; | |
| $green: #AFC7B9; | |
| $navy: #34495e; | |
| @import url("https://www.markmurray.co/codepen/customstyle.css"), url("https://fonts.googleapis.com/css?family=Lato:300,400,700"); | |
| html, body { | |
| background: $green; | |
| font-family: 'Lato', sans-serif; | |
| height: 100%; | |
| padding: 1em; | |
| } | |
| .left { text-align: left!important } | |
| .center { text-align: center!important } | |
| .right { text-align: right!important } | |
| .container { | |
| max-width: 1080px; | |
| margin: 0 auto; | |
| height: 100%; | |
| } | |
| .box { | |
| width: 49%; | |
| background: #f3f3f3; | |
| margin: 0 auto 2em auto; | |
| overflow: auto; | |
| padding: 1em; | |
| border-radius: 3px; | |
| display: inline-block; | |
| vertical-align: top; | |
| &:first-child{ | |
| margin-right: 1%; | |
| } | |
| } | |
| h1 { | |
| color: #3a3a3a; | |
| text-align: center; | |
| margin: 1em 0; | |
| } | |
| table { | |
| border: none; | |
| outline: none; | |
| width: 100%; | |
| margin: 0.5em 0 1em; | |
| tr.table-header { | |
| td { | |
| font-size: 0.7em; | |
| font-weight: bolder; | |
| } | |
| } | |
| td { | |
| padding: 0.75em 0.5em; | |
| } | |
| td:first-child { | |
| text-align: left; | |
| } | |
| td:nth-child(3){ | |
| text-align: center; | |
| } | |
| td:last-child, td:nth-child(4){ | |
| text-align: right; | |
| } | |
| tr:nth-child(2n+2){ | |
| background: darken(#eee, 1%); | |
| } | |
| } | |
| .searchButton { | |
| border: 1px solid #e0e0e0; | |
| background: #fff; | |
| outline: none; | |
| padding: 1em; | |
| border-radius: 3px; | |
| font-weight: 300; | |
| font-size: 0.8em; | |
| margin-top: 0.25em; | |
| margin-bottom: 0.25em; | |
| position: relative; | |
| } | |
| .margin-right { | |
| margin-right: 1%; | |
| } | |
| .half { | |
| width: 49.5%; | |
| display: inline-block; | |
| input { | |
| width: 100%; | |
| } | |
| } | |
| .half:first-child { | |
| margin-right: 2%; | |
| } | |
| .selected { | |
| text-decoration: line-through; | |
| color: #aaa; | |
| } | |
| .dollar { | |
| position: relative; | |
| display: inline-block; | |
| } | |
| .dollar input { | |
| padding-left: 2em; | |
| } | |
| .dollar span { | |
| position: absolute; | |
| display: block; | |
| padding: 3px 3px 3px 7px; | |
| pointer-events: none; | |
| left: 5px; top: 13px; | |
| color: #aaa; | |
| z-index: 1; | |
| } | |
| .searchButton.full { | |
| width: 100%; | |
| } | |
| .list { | |
| font-family: 'Lato', sans-serif; | |
| font-weight: 300; | |
| ul { | |
| li { | |
| margin: 1em 0; | |
| } | |
| } | |
| } | |
| .inventory h1 { | |
| color: #3a3a3a; | |
| padding-top: 5px; | |
| font-family: 'Lato', sans-serif; | |
| text-align: center; | |
| } | |
| input[type='checkbox']{ | |
| background: transparent; | |
| border: 2px solid #3a3a3a; | |
| padding: 0.2em; | |
| font-size: 1em; | |
| } | |
| button.clear { | |
| background: lighten($navy, 6%); | |
| border-bottom: 4px solid darken($navy, 5%); | |
| } | |
| button.clear:hover { | |
| background: lighten($navy, 2%); | |
| border-bottom: 2px solid darken($navy, 5%); | |
| } | |
| button { | |
| margin: 0.25em 0; | |
| display: block; | |
| outline: none; | |
| background: $red; | |
| border: none; | |
| padding: 1.1em; | |
| border-radius: 6px; | |
| width: 100%; | |
| color: white; | |
| text-transform: uppercase; | |
| cursor: pointer; | |
| border-bottom: 4px solid darken($red, 5%); | |
| &:hover { | |
| border-bottom: 2px solid darken($red, 5%); | |
| margin-bottom: 0.9em; | |
| @include box-shadow(inset 0 0 10px 0px rgba(black, 0.2)); | |
| } | |
| } | |
| .cost { | |
| margin-bottom: 1em; | |
| span { | |
| padding: 0.5em; | |
| &:first-child { | |
| float: left; | |
| } | |
| &:nth-child(2){ | |
| float: right; | |
| vertical-align: baseline; | |
| } | |
| } | |
| } | |
| .total { | |
| background: $red; | |
| color: white; | |
| font-weight: bolder; | |
| border-radius: 5px; | |
| } | |
| #successMessage, #errorMessage { | |
| display: none; | |
| text-align: center; | |
| margin: 0.5em 0; | |
| @include transition(display 0.3s ease); | |
| } | |
| i { | |
| vertical-align: baseline; | |
| margin-right: 0.5em; | |
| border-radius: 50%; | |
| width: 0.5em; height: 0.5em; | |
| padding: 0.5em; | |
| font-size: 0.8em; | |
| color: white; | |
| } | |
| i.icon-checkmark { | |
| background: green; | |
| } | |
| i.icon-cross { | |
| background: red; | |
| } | |
| i.delete { | |
| color: lighten($red, 8%); | |
| background: transparent; | |
| font-size: 1.1em; | |
| vertical-align: sub; | |
| cursor: pointer; | |
| &:hover { | |
| color: darken($red, 8%); | |
| } | |
| } | |
| #successMessage { | |
| color: green; | |
| } | |
| #errorMessage { | |
| color: red; | |
| } | |
| @media (max-width: 800px) { | |
| .box { | |
| width: 100%; | |
| display: block; | |
| } | |
| } | |
| /* Clearfix */ | |
| .cf:before, | |
| .cf:after { | |
| content: " "; /* 1 */ | |
| display: table; /* 2 */ | |
| } | |
| .cf:after { | |
| clear: both; | |
| } | |