Sunday, January 31, 2016

AngularJS : Create a web site using Angular JS, ASP.net MVC, web api - PART 4 : Coding client side


PLAN

Introduction

In this article we will implement the client side using angularjs.

Using the code

I) Project tree

the client project tree is constituted by three parts :
1) Controllers folder : contains the declaration of controllers.
2) Services folder  : has the declaration of custom services related to each controllers.
2) View : contains html pages and a js file that contains the initialization of different module and routes.
the following picture,  can more explain the organisation of our project  :


II) Routing

the routing part, is very useful because it defines the internal navigation of our client-side.
 // include ngRoute for all our routing needs  
 var appConnexion = angular.module('appConnexion', ['ngRoute']);  
 // configure routes for SignIn & SingUp space   
 appConnexion.config(function ($routeProvider, $locationProvider) {  
   $routeProvider  
     //route for the Login html page  
     .when('/login', {  
       templateUrl: 'app/Login.html',  
       controller: 'loginController'  
     })  
     // route for the Signup html page  
     .when('/signup', {  
       templateUrl: 'app/Signup.html',  
       controller: 'signupController'  
     }).otherwise({ redirectTo: '/login' });  
   $locationProvider.html5Mode({  
     enabled: true,  
     requireBase: false  
   });//fix url problem*/  
 });  
 var appConsumer = angular.module('appConsumer', ['ngRoute']);  
 // configure routes for Consumer space   
 appConsumer.config(function ($routeProvider, $locationProvider) {  
   $routeProvider  
     //route for the ConsumerProducts.html  
     .when('/consumerproducts', {  
       templateUrl: 'app/ConsumerProducts.html',  
       controller: 'ConsumerController'  
     })  
     //route for the ConsumerCommand.html  
     .when('/consumercommand', {  
       templateUrl: 'app/ConsumerCommand.html',  
       controller: 'ConsumerController'  
     })  
      //route for the ConsumerCart.html  
     .when('/consumercart', {  
       templateUrl: 'app/ConsumerCart.html',  
       controller: 'ConsumerController'  
     })  
     .otherwise({ redirectTo: '/consumerproducts' });  
   $locationProvider.html5Mode({  
     enabled: true,  
     requireBase: false  
   });//fix url problem*/  
 });  
 var appAdmin = angular.module('appAdmin', ['ngRoute']);  
 // configure routes for Admin space   
 appAdmin.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {  
   $routeProvider  
     //route for AdminProducts.html  
     .when('/adminproducts', {  
       templateUrl: 'app/AdminProducts.html',  
       controller: 'AdminController'  
     })  
     //route for AdminCommand.html  
     .when('/admincommand', {  
       templateUrl: 'app/AdminCommand.html',  
       controller: 'AdminController'  
     })   
     .otherwise({ redirectTo: '/adminproducts' });  
   $locationProvider.html5Mode({  
     enabled: true,  
     requireBase: false  
   });//fix url problem*/  
 }]);  
 

III) Services

In this section, each service created, contains a list of functions that build a request (http) which point to a specific url (url of service in Server side).
these services will be called from controller to execute some specific actions.

1) AdminServices (AdminServices.js)
return functions that build a http request :
  • ProductsList: return http request that point to : api/Services/ProductList .
  • CommandsList: return http request that point to : api/Services/CommandsList.
  • insertProduct: return http request that point to : api/Services/insertProduct.
  • updateProduct: return http request that point to : api/Services/updateProduct.
  • updateCommand: return http request that point to : api/Services/updateCommand.

  appAdmin.factory('DataServiceA', ['$http', function ($http) {  
   var ProductsList = function () {  
     return $http.get("api/Services/ProductsList");  
   }  
   var CommandsList = function (loginUser) {  
     var parameters = {  
       loginUser: loginUser  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/CommandsList", config);  
   }  
   var updateCommand = function (commandId, status) {  
     var parameters = {  
       commandId: commandId,  
       status: status  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/updateCommand", config);  
   }  
   var insertProduct = function (fd) {  
     return $http.post("api/Services/insertProduct", fd, {  
       transformRequest: angular.identity,  
       headers: { 'Content-Type': undefined }  
     });  
   }  
   var updateProduct = function (fd) {  
     return $http.post("api/Services/updateProduct", fd, {  
       transformRequest: angular.identity,  
       headers: { 'Content-Type': undefined }  
     });  
   }  
   return {  
     ProductsList: ProductsList,  
     CommandsList: CommandsList,  
     insertProduct: insertProduct,  
     updateProduct: updateProduct,  
     updateCommand: updateCommand,  
   }  
 }]);   


2) ConsumersServices (ConsumersServices.js)
return functions that build a http request :
  • ProductsList: return http request that point to : api/Services/ProductList .
  • CommandsList: return http request that point to : api/Services/CommandsList.
  • insertCommand: return http request that point to : api/Services/insertCommand.
 appConsumer.factory('DataServiceC', ['$http', function ($http) {  
   var ProductsList = function () {  
     return $http.get("api/Services/ProductsList");  
   }  
   var CommandsList = function (loginUser) {  
     var parameters = {  
       loginUser: loginUser  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/CommandsList", config);  
   }  
   var insertCommand = function (shoppingcart) {  
     var parameters = {  
       shoppingcart: shoppingcart,  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/insertCommand", config);  
   }  
   return {  
     ProductsList: ProductsList,  
     CommandsList: CommandsList,  
     insertCommand: insertCommand,  
   }  
 }]);  

3) LoginSignUpServices (LogInSignUpServices.js)

return functions that build a http request :
  • userExist : return http request that point to : api/Services/userExist.
  • insertUser: return http request that point to : api/Services/insertUser.

 appConnexion.factory('DataService', ['$http', function ($http) {  
   var userExist = function (loginUser, mp) {  
     var parameters = {  
       loginUser: loginUser,  
       mp : mp  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/userExist", config);  
   }  
   var insertUser = function (loginUser, mpUser) {  
     var parameters = {  
       loginUser: loginUser,  
       mpUser: mpUser,  
     };  
     var config = {  
       params: parameters  
     };  
     return $http.get("api/Services/insertUser", config);  
   }  
   return {  
     userExist: userExist,  
     insertUser: insertUser  
   }  
 }]);   

IV) Controller

1) AdminController (AdminCtrl.js)

the main functionalities of this controller are :
  • getting a list of available product
  • filtering product list by name
  • updating a specific product details
  • get list of commands
  • update the state of specific command

 appAdmin.controller('AdminController', ['$scope', '$route', '$routeParams', '$location', 'DataServiceA', function ($scope, $route, $routeParams, $location, DataServiceA) {  
   $scope.term = '';  
   $scope.selectedState = "Processing";  
   $scope.data = {  
     availableOptions: [  
      { id: 'Received', name: 'Received' },  
      { id: 'Processing', name: 'Processing' },  
      { id: 'Finish', name: 'Finish' }  
     ]};  
     getProducts();  
     function getProducts() {  
       DataServiceA.ProductsList().then(function (response) {  
         $scope.productList = response.data;  
       });  
     }  
     getCommands();  
     function getCommands() {  
       DataServiceA.CommandsList().then(function (response) {  
         $scope.commandList = response.data;  
       });  
     }  
     $scope.updateCommand = function (commandId, status) {  
       DataServiceA.updateCommand(commandId, status).then(function (response) {  
         alert("Change is saved");  
       });   
     }  
     function insertProduct(ProductName, ProductDescription, ProductPrice) {  
       var file = $('#myFile')[0].files[0];  
       var fd = new FormData();  
       fd.append("file", file);  
       fd.append("ProductName", ProductName);  
       fd.append("ProductDescription", ProductDescription);  
       fd.append("ProductPrice", ProductPrice);  
       DataServiceA.insertProduct(fd).then(function (response) {  
         getProducts();  
         alert("Product is inserted");  
         });  
       }  
     function updateProduct(productKey, ProductName, ProductDescription, ProductPrice) {  
       var file = $('#myFile')[0].files[0];  
       var fd = new FormData();  
       fd.append("file", file);  
       fd.append("productKey", productKey);  
       fd.append("ProductName", ProductName);  
       fd.append("ProductDescription", ProductDescription);  
       fd.append("ProductPrice", ProductPrice);  
       DataServiceA.updateProduct(fd).then(function (response) {  
         getProducts();  
         alert("Changes are done");  
       });  
     }  
   //product section  
      $scope.stateFormShow = false;  
      $scope.stateIsUpdate = false;  
      $scope.showFormAddProduct = function () {  
        $scope.master = null;  
        $scope.stateFormShow = true;  
        $scope.stateIsUpdate = false;  
      };  
     $scope.bindProductDetails = function (elem) {  
     $scope.stateFormShow = true;  
     $scope.stateIsUpdate = true;  
     $scope.master = angular.copy(elem);   
   }  
   //end Product section  
   $scope.saveP = function () {    
     if ($scope.stateIsUpdate == false) {  
       insertProduct($scope.master.nameProduct, $scope.master.descriptionProduct, $scope.master.price);  
     } else {  
       updateProduct($scope.master.idProduct, $scope.master.nameProduct, $scope.master.descriptionProduct, $scope.master.price);  
     }  
   };  
 }]);  
 //create filter by product name  
 appAdmin.filter('fetch', function () {  
   return function (items, term) {  
     term = term.toUpperCase();  
     if (term.length > 0) {  
       var filteredInput = [];  
       angular.forEach(items, function (item) {  
         if (item.nameProduct.toUpperCase().search(term) != -1) {  
           filteredInput.push(item);  
         }  
       });  
        return filteredInput;  
     } else {  
       return items;  
     }  
   };  
 });   

2) ConsumerController (ConsumersCtrl.js)
the main functionalities of this controller are :
  • getting a list of available product,
  • filtering product list by name,
  • add product to shopping cart,
  • get list of current user commands,
  • showing list of product in shopping cart list,
  • remove some product from shopping cart list,
  • validate transaction.
 appConsumer.controller('ConsumerController', ['$scope', '$rootScope', '$http', '$location', 'DataServiceC', function ($scope, $rootScope, $http, $location, DataServiceC) {  
   $scope.term = '';  
   getProducts();  
    function getProducts() {  
      DataServiceC.ProductsList().then(function (response) {  
        $scope.productList = response.data;  
      });  
     //redirection  
    }  
    getCommands();  
    function getCommands() {  
      DataServiceC.CommandsList("UserIsLoggged").then(function (response) {  
        $scope.commandList = response.data;  
     });  
     //redirection  
   }   
    insertCommand();  
    function insertCommand() {  
     $scope.insertCommand = function () {  
       DataServiceC.insertCommand($rootScope.Cart).then(function (response) {  
         alert("Command successfully saved");  
         initializeCart(true);  
       });  
     }   
    }  
   //product section  
    $scope.stateFormShow = false;  
    $scope.bindProductDetails = function (elem) {  
      $scope.stateFormShow = true;  
      $scope.master = angular.copy(elem);  
    }  
   //end Product section  
   //Cart Section  
    function initializeCart(empty) {  
      $scope.CartIsNotEmpty = false;  
      if (angular.isUndefined($rootScope.Cart) || empty == true) {  
        $rootScope.Cart = {};  
        $rootScope.CartList = new Array();  
      }  
      if ($rootScope.CartList.length > 0) {  
        $scope.CartIsNotEmpty = true;  
      }  
    }  
    initializeCart(false);  
    $scope.AddToCart = function () {  
      if (angular.isUndefined($scope.Cart[$scope.master.idProduct]) ) {  
        $rootScope.Cart[$scope.master.idProduct] = 1;  
        $rootScope.CartList.push(angular.copy($scope.master));  
      }else{  
        $rootScope.Cart[$scope.master.idProduct]++;  
      }  
    }  
    $scope.RemoveFromCart = function (elem) {  
      delete $rootScope.Cart[elem.idProduct];  
      var i = 0;   
      angular.forEach($rootScope.CartList, function (item) {  
        if (item.idProduct == elem.idProduct) {         
          $rootScope.CartList.splice(i,1);  
          return;  
        }  
        i++;  
      });  
    }  
   //End Cart section  
 }]);  
 appConsumer.filter('fetch', function () {  
   return function (items, term) {  
     term = term.toUpperCase();  
     if (term.length > 0) {  
       var filteredInput = [];  
       angular.forEach(items, function (item) {  
         if (item.nameProduct.toUpperCase().search(term) != -1) {  
           filteredInput.push(item);  
         }  
       });  
       // conditional based on optional argument  
       return filteredInput;  
     } else {  
       return items;  
     }  
   };  
 });  

3) loginController (LogInSignUpCtrl.js)

the main functionalities of this controller are :
  • check if the input login and password is for an existing user.
  • registring a new user.
 appConnexion.controller('loginController', ['$scope', '$location', 'DataService', function ($scope, $location, DataService) {  
   $scope.GoLogin = function(login, mp)  
   {  
     //assure la navigation angular  
     DataService.userExist(login, mp).then(function (response) {  
           switch (response.data){  
             case "A": {  
               window.location = "/Home/Admin?login="+ login;  
                break;  
             }  
             case "U": {  
               window.location = "/Home/Consumer?login=" + login;  
                break;  
             }  
             default:{  
               alert("User not exist");  
             }  
           }  
     });  
   }  
 }]);  
 appConnexion.controller('signupController', ['$scope', '$location', 'DataService', function ($scope, $location, DataService) {  
   $scope.GoSingup = function(login, mp)  
    {  
     //assure la navigation angular  
     //.then(function (response) { alert(response.data); })  
     DataService.insertUser(login, mp).then(function (response) { alert(response.data); });  
     //$location.path("/signup");  
    }  
 }]);  

V) View

  • Login.html

  <div class="row">  
    <div style="background-color:whitesmoke; border-radius:4px" class="col-sm-4 col-sm-offset-4">  
      <h2>Please Sign in</h2>  
      <form role="form">  
        <div class="form-group">  
          <label for="email">Email address:</label>  
          <input type="text" ng-model="login" placeholder="Username" class="form-control">  
        </div>  
        <div class="form-group">  
          <label for="pwd">Password:</label>  
          <input type="text" ng-model="mp" placeholder="Password" class="form-control">  
        </div>  
        <button type="button" ng-click="GoLogin(login, mp)" class="btn btn-default">Sign In</button> &ensp; <a href="/signup"> Sign Up</a>  
      </form>  
      <br>  
    </div>  
    <div class="col-sm-4"></div>  
 </div>  

  • Signup.html

 <div class="row">  
   <div class="login-form">  
     <h2>Please Sign up</h2>  
     <form role="form">  
       <div class="form-group">  
         <label for="email">Email address:</label>  
         <input type="text" ng-model="login" placeholder="Username" class="form-control">  
       </div>  
       <div class="form-group">  
         <label for="pwd">Password:</label>  
         <input type="text" ng-model="mp" placeholder="Password" class="form-control">  
       </div>  
       <button type="button" ng-click="GoSingup(login, mp)" class="btn btn-default">Sign Up</button>&ensp; <a href="/login"> Login</a>  
     </form>  
   </div>  
 </div>  

  • ConsumerProducts.html

 <div class="row">  
   <div class="cols"></div>  
   <div class="col-sm-3">  
     <div>  
       <form role="search">  
         <label>Search Product </label>  
         <div class="form-group">  
           <div class="form-group">  
             <input class="form-control" type="text" ng-model="term" placeholder="filter by name" />  
           </div>  
          </div>  
       </form>  
     </div>  
     <br>  
     <div>  
       <div ng-repeat="elem in productList | fetch : term">  
         <div ng-click="bindProductDetails(elem)">  
           <div class="row">  
             <div class="col-sm-8">  
               <img class="img-thumbnail" ng-src="/Content/Images/{{elem.imageProduct}}"></img>  
              </div>  
             <div class="col-sm-4 left">  
               <label>  
                 {{elem.nameProduct}}  
               </label>  
             </div>  
           </div>  
         </div>  
       </div>  
     </div>  
   </div>  
   <div class="col-sm-9">  
     <br><br>  
     <br><br>  
     <div class="row" ng-show="stateFormShow">  
       <div class="row box-shadow">  
         <div class="col-md-4">  
           <img class="img-thumbnail" ng-src="/Content/Images/{{master.imageProduct}}"></img>  
         </div>  
         <div class="col-md-4">  
           <div class="lib-row lib-header">  
             <strong>  
               {{master.nameProduct}}  
             </strong>  
             <div class="lib-header-seperator"></div>  
           </div>  
           <div class="lib-row lib-desc">  
             {{master.descriptionProduct}}  
           </div>  
           <div><button class="btn btn-lg btn-primary" ng-click="AddToCart()"><span class="glyphicon glyphicon-shopping-cart"></span> Add to cart</button></div>  
         </div>  
         <div class="col-md-offset-4"></div>  
       </div>  
     </div>  
   </div>  
 </div>  

  • ConsumerCommand.html

 <div class="row col-md-6">  
   <div class="panel panel-default">  
     <!-- Default panel contents -->  
     <div class="panel-heading">Commands List</div>  
     <table class="table table-responsive">  
       <thead>  
         <tr>  
           <th>Command Date</th>  
           <th>Product Name</th>  
           <th>Status</th>  
         </tr>  
       </thead>  
       <tbody ng-repeat="cmd in commandList">  
         <tr>  
           <td>{{cmd.CommandDate}}</td>  
           <td>{{cmd.ProductName}}</td>  
           <td>{{cmd.Status}}</td>  
         </tr>  
       </tbody>  
     </table>  
   </div>  
 </div>  

  • ConsumerCart.html

 <div class="row col-md-8">  
   <div class="panel panel-default">  
     <!-- Default panel contents -->  
     <div class="panel-heading">Shopping List</div>  
     <table class="table">  
       <thead>  
         <tr>  
           <th></th>  
           <th>Details</th>  
           <th>Count</th>  
           <th></th>  
         </tr>  
       </thead>  
       <tbody ng-repeat="cart in CartList">  
         <tr>  
           <td class="col-md-3">  
             <img class="img-responsive" width="100" height="100" ng-src="/Content/Images/{{cart.imageProduct}}"></img>  
           </td>  
           <td class="col-md-3">  
             <strong>{{cart.nameProduct}}</strong>  
             <br />  
             {{cart.descriptionProduct}}  
           </td>  
           <td class="col-md-3">  
             {{Cart[cart.idProduct]}}  
           </td>  
           <td class="col-md-3">  
             <a href="#" ng-click="RemoveFromCart(cart)"><span class="glyphicon glyphicon-remove"></span></a>  
           </td>  
         </tr>  
       </tbody>  
     </table>  
     <div class="panel-footer">  
       <button class="btn btn-default btn-primary" ng-show="CartIsNotEmpty" ng-click="insertCommand()">  
         <span class="glyphicon glyphicon-shopping-cart"> Buy</span>  
       </button>  
     </div>  
   </div>  
 </div>  

  • AdminCommand.html

 <div class="row col-md-6">  
   <div class="panel panel-default">  
     <!-- Default panel contents -->  
     <div class="panel-heading">Current Command List</div>  
     <table class="table">  
       <thead>  
         <tr>  
           <th>Command Date</th>  
           <th>Product Name</th>  
           <th>Consumer</th>  
           <th>Status</th>  
         </tr>  
       </thead>  
       <tbody ng-repeat="cmd in commandList">  
         <tr>  
           <td>{{cmd.CommandDate}}</td>  
           <td>{{cmd.ProductName}}</td>  
           <td>{{cmd.loginUser}}</td>  
           <td>  
             <select name="repeatSelect" id="repeatSelect"  
                 ng-change="updateCommand(cmd.CommandId, cmd.Status)" ng-model="cmd.Status">  
               <option value="Received">Received</option>  
               <option value="Processing">Processing</option>  
               <option value="Finish">Finish</option>  
             </select>  
           </td>  
         </tr>  
       </tbody>  
     </table>  
   </div>  
  </div>  

  • AdminProducts.html

 <div class="row">  
   <div class="col-sm-3">  
     <div>  
       <form role="search">  
         <label>Search Product </label>  
           <div class="form-group">  
             <div class="col-sm-8 form-group">  
               <input class="form-control" type="text" ng-model="term" placeholder="filter by name" />  
             </div>  
             <a ng-click="showFormAddProduct()" class="btn btn-default btn-circle"><span class="glyphicon glyphicon-plus-sign"></span></a>  
           </div>  
       </form>  
     </div>  
     <br>  
     <div>  
       <div ng-repeat="elem in productList | fetch : term">  
         <div ng-click="bindProductDetails(elem)">  
           <div class="row">  
             <div class="col-sm-8">  
               <img class="img-thumbnail" ng-src="/Content/Images/{{elem.imageProduct}}"></img>  
             </div>  
             <div class="col-sm-4 left">  
               <label>  
                 {{elem.nameProduct}}  
               </label>  
             </div>  
           </div>  
         </div>  
       </div>  
     </div>  
   </div>  
   <div class="col-sm-9">  
     <br>  
     <br>  
     <br>  
     <br>  
     <form class="form-horizontal ng-hide" ng-show="stateFormShow">  
       <div class="form-group" ng-show="stateIsUpdate">  
         <label for="inputEmail3" class="col-sm-2 control-label">ID</label>  
         <div class="col-sm-10">  
           <input type="text" value="{{master.idProduct}}" ng-model="master.idProduct" class="form-control" placeholder="put Product Name" readonly>  
         </div>  
       </div>    
       <div class="form-group">  
         <label for="inputEmail3" class="col-sm-2 control-label">Name</label>  
         <div class="col-sm-10">  
           <input type="text" value="{{master.nameProduct}}" ng-mod ng-model="master.nameProduct" class="form-control" placeholder="Put Product Nam" />  
         </div>  
       </div>  
       <div class="form-group">  
         <label for="inputEmail3" class="col-sm-2 control-label">Description</label>  
         <div class="col-sm-10">  
           <textarea ng-model="master.descriptionProduct" class="form-control" placeholder="Put description">{{master.descriptionProduct}}</textarea>  
         </div>  
       </div>  
       <div class="form-group">  
         <label for="inputEmail3" class="col-sm-2 control-label">Age</label>  
         <div class="col-sm-10">  
           <input type="number" value="{{master.price}}" ng-model="master.price" class="form-control" placeholder="Age">  
         </div>  
       </div>  
       <div class="form-group">  
         <label for="inputEmail3" class="col-sm-2 control-label">File</label>  
         <div class="col-sm-10">  
           <input type="file" id="myFile" name="myFile" />  
         </div>  
       </div>  
       <div class="form-group">  
         <div class="col-sm-offset-2 col-sm-10">  
           <button type="submit" ng-click="saveP()" class="btn btn-default">Save</button>  
         </div>  
       </div>  
     </form>  
   </div>  
 </div>  

VI) User interface manipulation

 

1) Authentification Space

Sign In interface


Sing Up interface


2) Admin Space 

Admin Authentification



Admin Home


Add a new product
 
1) clic on + icon

 
 
2) complete product form and clic on save button


 
 

Modify existing product

1) choose a product

 
 
2) change details and click on save button.

 
 

Chaging command state

1) click on Commands item in the top menu to show available commands.

 
 
2) for a selected command, modify current state by choosing a new state from drop down menu list.

 
 

3) Consumer Space 

Searching product by name


 
 

View product details 

1) select a product, to show its description .

 
 

Add product to shopping cart

1) by clicking on the 'Add to Cart' button shown in the details of each product, your choice will be add into shopping cart list.
 
 
 

Buy products

1) in the cart interface, you can click on  'Buy' button to lunch a new purchase order.

 
 

Viewing customer command list



Conclusion

I hope that you appreciated my effort. Thank you for viewing my blog post, try to download the source code and do not hesitate to leave your questions and comments.

No comments:

Post a Comment